124
Working With Web Services Rob Richards May 20, 2008 http://xri.net/=rob.richards

Working With Web Services - CDATA Zonecdatazone.org/talks/phptek_2008/Working_Web_Svcs.pdf · GET / POST • More Service Oriented – Actions are performed on the same/similar endpoints

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

  • Working With Web ServicesRob Richards

    May 20, 2008

    http://xri.net/=rob.richards

    http://xri.net/=rob.richardshttp://xri.net/=rob.richards

  • • GET / POST

    • Restful

    • REST

    • XML-RPC

    • JSON-RPC

    • SOAP

    Common Types Of Services

    2

  • GET / POST

    • More Service Oriented– Actions are performed on the same/similar endpoints

    – Parameters or Body drive actions

    – Tend to be more free for all in design

    – Perform Read/Write operations

    • Any data format supported– XML

    – JSON

    Examples From Amazon EC2 Servicehttps://ec2.amazonaws.com/?Action=AllocateAddress&AWSAccessKeyId=...

    https://ec2.amazonaws.com/?Action=CreateKeyPair&KeyName=example-key-name&AWSAccessKeyId=...

    https://ec2.amazonaws.com/?Action=DescribeInstances&AWSAccessKeyId=...

    3

    https://ec2.amazonaws.com/?Action=AllocateAddress&AWSAccessKeyId=https://ec2.amazonaws.com/?Action=AllocateAddress&AWSAccessKeyId=https://ec2.amazonaws.com/?Action=CreateKeyPair&KeyName=example-key-name&AWSAccessKeyId=https://ec2.amazonaws.com/?Action=CreateKeyPair&KeyName=example-key-name&AWSAccessKeyId=https://ec2.amazonaws.com/?Action=CreateKeyPair&KeyName=example-key-name&AWSAccessKeyId=https://ec2.amazonaws.com/?Action=CreateKeyPair&KeyName=example-key-name&AWSAccessKeyId=

  • Amazon Simple Queue Service

    $url = 'http://queue.amazonaws.com/queue1';$params = array('Action'=>'SendMessage', 'MessageBody' => 'Your%20Message%20Text', 'AWSAccessKeyId'=>'0GS755xyzEXAMPLE', . . .);

    $post_body = http_build_query($params);$context_params = array( 'http' => array( 'method' => 'POST', 'header' => 'Content-Type: application/x-www-form-urlencoded', 'content' => $post_body ));$file_context = stream_context_create($context_params);

    $results = file_get_contents($url, false, $file_context);var_dump($results);

    4

    http://queue.amazonaws.com/queue1'http://queue.amazonaws.com/queue1'

  • RESTful

    • Generally follow REST guidelines

    • Read-only data using HTTP GET

    • URL path typically does not refer to resource

    • Parameters influence results

    Yahoo Image Search

    http://search.yahooapis.com/ImageSearchService/V1/imageSearch?appid=YahooDemo&query=PHP+elephant&output=json

    {"ResultSet":{"totalResultsAvailable":"561","totalResultsReturned":10,"firstResultPosition":1,"Result":[{"Title":"php_elephant.jpg","Summary":"php_elephant.jpg","Url":"http:\/\/vizzed.com\/VizzedBoardFiles\/upload\/php_elephant.jpg","ClickUrl":"http:\/\/vizzed.com\/VizzedBoardFiles\/upload\/php_elephant.jpg","RefererUrl":"http:\/\/vizzed.com\/VizzedBoardFiles\/upload","FileSize":7065,"FileFormat":"jpeg","Height":"96","Width":"150","Thumbnail":{"Url":"http:\/\/re3.yt-thm-a01.yimg.com\/image\/25\/m1\/2070796738","Height":"80","Width":"125"}} . . .

    5

    http://search.yahooapis.com/ImageSearchService/V1/imageSearch?appid=YahooDemo&query=PHP+elephant&output=jsonhttp://search.yahooapis.com/ImageSearchService/V1/imageSearch?appid=YahooDemo&query=PHP+elephant&output=jsonhttp://search.yahooapis.com/ImageSearchService/V1/imageSearch?appid=YahooDemo&query=PHP+elephant&output=jsonhttp://search.yahooapis.com/ImageSearchService/V1/imageSearch?appid=YahooDemo&query=PHP+elephant&output=json

  • Representational State Transfer: REST

    • Endpoints are resource identifiers– A resource is any named item

    – Resources are identified by URLs

    • Architectural style not a standard

    • Builds upon standards– HTTP

    – URLS

    – Mime types

    • HTTP methods determine action

    • Google APIs are good examples– Calendar

    – Spreadsheet

    – Notebook

    6

  • HTTP Methods & Actions

    7

    HTTP CRUD

    POST CREATE

    GET RETRIEVE

    PUT UPDATE

    DELETE DELETE

    HTTP CRUD

    POST CREATE/UPDATE/DELETE

    GET RETRIEVE

    PUT CREATE/UPDATE

    DELETE DELETE

    Formal Operations Relaxed Operations

  • REST Retrieve Data

    Retrieve private entries from a personal calendarUses HTTP GET

    Retrieve All Entries:http://www.google.com/calendar/feeds//private/full

    Retreive Specific Entry:http://www.google.com/calendar/feeds//private/full/cmanvsln9jk5e

    Limit To Entries Within Date Range:http://www.google.com/calendar/feeds//private/full?start-min=2008-05-01T00:00:00&start-max=2008-05-31T23:59:59

    8

    http://www.google.com/calendar/feeds/http://www.google.com/calendar/feeds/http://www.google.com/calendar/feeds/http://www.google.com/calendar/feeds/http://www.google.com/calendar/feeds/http://www.google.com/calendar/feeds/

  • REST: Google Calendar Entry

    http://www.google.com/calendar/feeds/default/private/full/asdc 2008-05-13T23:36:58.000Z 2008-05-13T23:44:44.000Z Tennis with John Meet for a quick lesson.. . . Rob Richards . . .

    9

    http://www.google.com/calendar/feeds/default/private/full/http://www.google.com/calendar/feeds/default/private/full/http://schemas.google.com/g/2005#kindhttp://schemas.google.com/g/2005#kindhttp://schemas.google.com/g/2005#eventhttp://schemas.google.com/g/2005#eventhttp://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/cbdmc5lksen8idhspn9jk5i76k/commentshttp://www.google.com/calendar/feeds/default/private/full/cbdmc5lksen8idhspn9jk5i76k/comments

  • REST Create Entry

    POST Entry Datahttp://www.google.com/calendar/feeds/default/owncalendars/full

    • URL Is Same As One Used By Calendar Retrieval• Content-Type is application/atom+xml• Successful Creation

    - 201 Created status returned- Newly created Entry returned

    • Failure returns other GData Status Code

    10

    http://www.google.com/calendar/feeds/default/owncalendars/fullhttp://www.google.com/calendar/feeds/default/owncalendars/full

  • REST Update Entry

    URL used to edit an entry is located in the edit link:

    HTTP PUT edited entry to edit URL

    http://www.google.com/calendar/feeds/default/private/full/asdc 2008-05-13T23:36:58.000Z 2008-05-14T23:44:44.000Z Tennis with John Meet for a quick lesson.. . . Rob Richards . . .

    11

    http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/asdchttp://www.google.com/calendar/feeds/default/private/full/asdc

  • REST Delete Entry

    HTTP DELETE to edit URL

    http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484

    Successful deletion returns status 200

    12

    http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/asdc/63346405484http://www.google.com/calendar/feeds/default/private/full/cbdmc5lksen8idhspn9jk5i76k/63346405484http://www.google.com/calendar/feeds/default/private/full/cbdmc5lksen8idhspn9jk5i76k/63346405484http://www.google.com/calendar/feeds/default/private/full/cbdmc5lksen8idhspn9jk5i76k/63346405484http://www.google.com/calendar/feeds/default/private/full/cbdmc5lksen8idhspn9jk5i76k/63346405484

  • XML-RPC

    • XML-based Remote Procedure Call

    • Function call is marshaled

    • Data structure defines method, types and values

    • Parameters and return values are typed

    • Defines how the messages is to be transported– HTTP POST

    – Required HTTP Headers

    • More Tightly Coupled

    • Predecessor to SOAP

    13

  • XML-RPC Request

    HTTP POST: http://www.upcdatabase.com/rpc

    lookupUPC 021000013425

    14

  • upc 021000013425 description SUPER MAC & CHEESE SPONGE BO * size 5.5 oz

    XML-RPC Response

    15

  • JSON-RPC

    • Comparable to XML-RPC though using JSON

    • In addition to method and parameters, JSON-RPC includes an id property to map requests and responses

    • Defines one-way communications (notifications)

    • No specific transport protocol required

    • HTTP POST most common transport

    16

  • JSON-RPC Request

    HTTP POST:http://www.raboof.com/Projects/Jayrock/Demo.ashx

    Content-type: application/json

    {"method":"total","params":{"values":[1,2,3]},"id":55}

    $data = array("method"=>"total", "params"=>array("values"=>array(1,2,3)), "id" => 55);echo json_encode($data)."\n";$json = json_encode($data)

    17

    http://www.raboof.com/Projects/Jayrock/Demo.ashxhttp://www.raboof.com/Projects/Jayrock/Demo.ashx

  • JSON-RPC Response

    {"id":55,"result":6}

    $objResult = json_decode($results); echo $obResult->result."\n";

    18

  • SOAP

    • SOAP stands for ABSOLUTELY NOTHING!

    • Can be RPC or Message based

    • Strong data typing

    • Designed for interoperability

    • Can be simple to use

    • Allows for advanced communications– Standard security mechanisms

    – Message delivery guarantee

    – Additional out of band information

    – Addressing and callback capabilities

    19

  • SOAP Message

    [email protected] [email protected] this is a test test

    20

    http://schemas.xmlsoap.org/soap/envelope/http://schemas.xmlsoap.org/soap/envelope/http://schemas.xmlsoap.org/soap/encoding/http://schemas.xmlsoap.org/soap/encoding/mailto:[email protected]:[email protected]:[email protected]:[email protected]

  • SOAP Response

    21

    http://schemas.xmlsoap.org/soap/envelope/http://schemas.xmlsoap.org/soap/envelope/

  • Deciding Upon A Service

    With All The Different Types Of Services, How Do You Decide

    What To Use?

    ?22

  • Intended Audience

    • Exposing To The Masses

    • Internal Developers

    • Business Partners

    • Multiple Audiences

    23

  • Security Implications

    • Do you need to protect your data?

    • Do users need to be authenticated?

    • To what level do you need protection?

    • Are multiple parties involved?

    • Does the data pass through multiple systems?

    • Do you need granularity?

    24

  • What Is The Purpose?

    • Reduce system maintenance?

    • Expose existing logic as services?

    • Expose logic from legacy systems?

    • Aggregate functionality?

    25

  • Any Curveballs?

    • Two-phase commits

    • Asynchronous Messaging

    • Legacy System Protocols

    • Multi-System Involvement

    26

  • Let’s Get Our Hands Dirty!

  • Helpful Tools

    • Eclipse– WSDL Editor

    – XML / XSD Editors & Validators

    • Misc. XML Editors– XML NotePad 2007 (Microsoft)

    – XML Spy (Altova)

    • soapUI– http://www.soapui.org

    – Multiple platforms / Free & enhanced Pro versions

    • SOAPSonar– http://www.crosschecknet.com

    – Windows only / Free and Professional versions

    28

    http://www.soapui.orghttp://www.soapui.orghttp://www.crosschecknet.comhttp://www.crosschecknet.com

  • Yahoo Product Search

    // URL to Product Search service$url = 'http://shopping.yahooapis.com/ShoppingService/V3/productSearch?';

    // The query is separate here as the terms must be encoded.$url .= 'query='.rawurlencode('linksys');

    // Complete the URL with App ID, limit to 1 result and start at second record$url .= "&appid=zzz&results=2&start=2";

    $data = file_get_contents($url);

    echo $data;

    29

    http://shopping.yahooapis.com/ShoppingService/V3/productSearch?'http://shopping.yahooapis.com/ShoppingService/V3/productSearch?'

  • Not So Simple

    The following errors were detected:User-agent not valid

    30

    http://www.w3.org/2001/XMLSchema-instancehttp://www.w3.org/2001/XMLSchema-instancehttp://api.yahoo.com/Api/V1/error.xsdhttp://api.yahoo.com/Api/V1/error.xsdhttp://api.yahoo.com/Api/V1/error.xsdhttp://api.yahoo.com/Api/V1/error.xsd

  • Set The User Agent

    $context_params = array( 'http' => array( 'user_agent' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)' ));

    $file_context = stream_context_create($context_params);

    $data = file_get_contents($url, false, $file_context);

    echo $data;

    31

  • Yahoo Results

    Computers & Software 1can1acp 7196 Networking 1can1gnetwork 5308 Network Adapters 1can1cnetworkZZZ5Fadapter

    32

    http://www.w3.org/2001/XMLSchema-instancehttp://www.w3.org/2001/XMLSchema-instancehttp://www.w3.org/2001/XMLSchema-instancehttp://www.w3.org/2001/XMLSchema-instancehttp://shopping.yahooapis.com/shoppingservice/v3/productsearch.xsdhttp://shopping.yahooapis.com/shoppingservice/v3/productsearch.xsdhttp://shopping.yahooapis.com/shoppingservice/v3/productsearch.xsdhttp://shopping.yahooapis.com/shoppingservice/v3/productsearch.xsd

  • We Want To Use SimpleXML Directly!

    if ($sxe = simplexml_load_file($url)) { echo $sxe->Categories->SubCategory->Title;}

    PHP Notice: Trying to get property of non-object in /Users/rrichards/tests/php/yahoo/shop.php on line 23

    33

  • Stream Contexts and XML

    $context_params = array( 'http' => array( 'user_agent' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)' ));$xml_context = stream_context_create($context_params);

    libxml_set_streams_context($xml_context);

    if ($sxe = simplexml_load_file($url)) { echo $sxe->Categories->SubCategory->Title;}

    Computers & Software

    34

  • Google Calendar

    35

  • Google Calendar Login

    $url = 'https://www.google.com/accounts/ClientLogin';

    $params = array('Email'=>'[email protected]', 'Passwd' => , 'source'=>'phpwebsvc-1', 'service' => 'cl');

    $post_body = http_build_query($params);

    $context_params = array( 'http' => array( 'method' => 'POST', 'header' => 'Content-Type: application/x-www-form-urlencoded', 'content' => $post_body ));$file_context = stream_context_create($context_params);

    $results = file_get_contents($url, false, $file_context);

    36

    https://www.google.com/accounts/ClientLogin'https://www.google.com/accounts/ClientLogin'mailto:[email protected]:[email protected]

  • Google Calendar Login Using ext/http

    $url = 'https://www.google.com/accounts/ClientLogin';$params = array('Email'=>'[email protected]', 'Passwd' => , 'source'=>'phpwebsvc-1', 'service' => 'cl');

    $post_body = http_build_query($params);

    $req->setBody($post_body);

    $req->setContentType('application/x-www-form-urlencoded');

    $msg = $req->send();

    $results = $msg->getBody();

    37

    https://www.google.com/accounts/ClientLogin'https://www.google.com/accounts/ClientLogin'mailto:[email protected]:[email protected]

  • Google Calendar Our Login

    SID=DQAAAIkAAAAnSKcLgj-iO123456789012345123456789012345gHq_QlR2ruTbbDsXoB5H2OWsgg-E4tEeq7U23o1234567890123455v9Nsf6AkYdf1234567890123458eCEjr867-5dO3Needaa6xoltHi-ryWGKrui1234567890123455U4x9WN-vafQHx3JanyysLSID=DQAAAIoAAACEji868ECURZS3GDZsfls8nl-3O5WoiPzboDD2lwJkAmcQ0Sbyg3SPAe0yxiJa123456789012345yk9123456789012345jaYrUxHerwl1wD4Uz603z1234567890123457OkD4dTewAw6YVQRMin123234567890123458xpJ0rAx1saURz9RKTKbjen2AoAuth=DQAAAIoAAACEji123456789012345ls8nl-3O5WoiPzboDD2123456789012345PAe0yxiJa7Tfzeyk9eB4B0hMgT5t_1234567890123454ejaYrUxHekJqc4fe7SaZYd123456789012345SjUK1kLrCualqsZTpBpS-T123456789012345g3RobFeGDh2Yv-68nHffw

    38

  • Get Auth Token

    $tokens = split("\n", $results);foreach ($tokens AS $current) { $artemp = split("=", $current); if ($artemp[0] == 'Auth') { $token = $artemp[1]; break; }}

    39

  • Get Our Calendar Entries

    $url = 'http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full';

    $req = new HttpRequest($url, HttpRequest::METH_GET);

    $req->addHeaders(array('Authorization' => "GoogleLogin auth=$token"));

    $req->setOptions(array('redirect'=>1));

    $msg = $req->send();

    $cal = simplexml_load_string( $msg->getBody() );

    echo $cal->asXML();

    40

    http://www.google.com/calendar/feeds/default/owncalendars/full'http://www.google.com/calendar/feeds/default/owncalendars/full'http://www.google.com/calendar/feeds/default/owncalendars/full'http://www.google.com/calendar/feeds/default/owncalendars/full'

  • Our Calendar Entries

    http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full 3... http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1g 2008-05-17T16:23:49.000Z 2008-05-17T16:24:29.000Z Working With Web Services . . .

    41

    http://www.w3.org/2005/Atomhttp://www.w3.org/2005/Atomhttp://a9.com/-/spec/opensearchrss/1.0/http://a9.com/-/spec/opensearchrss/1.0/http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/fullhttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/fullhttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/fullhttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/fullhttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1ghttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1ghttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1ghttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1ghttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1ghttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1ghttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1ghttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1ghttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1g/63346724669http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1g/63346724669http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1g/63346724669http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1g/63346724669http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1g/63346724669http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/i3jg8t7ggoaj5l99dafue9ap1g/63346724669

  • New Entry

    Cocktails Mashery cocktail event

    42

    http://www.w3.org/2005/Atom'http://www.w3.org/2005/Atom'http://schemas.google.com/g/2005'http://schemas.google.com/g/2005'http://schemas.google.com/g/2005#kind'http://schemas.google.com/g/2005#kind'http://schemas.google.com/g/2005#event'http://schemas.google.com/g/2005#event'http://schemas.google.com/g/2005#event.opaque'http://schemas.google.com/g/2005#event.opaque'http://schemas.google.com/g/2005#event.confirmed'http://schemas.google.com/g/2005#event.confirmed'

  • Create The Entry

    $url = 'http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full';

    $req = new HttpRequest($url, HttpRequest::METH_POST);

    $req->setBody($myentry);

    $req->setContentType('application/atom+xml');$req->setOptions(array('redirect'=>3));

    $req->addHeaders(array('Authorization' => "GoogleLogin auth=$token"));

    $msg = $req->send();

    echo $msg->getBody();

    43

    http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full'http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full'http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full'http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full'

  • Now What???

    No Error, But No New Entry

    44

  • Inspecting The Transaction

    $req = new HttpRequest($url, HttpRequest::METH_POST);$req->setBody($myentry);

    $req->setContentType('application/atom+xml');$req->setOptions(array('redirect'=>3));$req->addHeaders(array('Authorization' => "GoogleLogin auth=$token"));

    $msg = $req->send();

    echo $msg->getBody();

    var_dump($msg->getParentMessage());

    45

  • Inspecting The Transaction

    . . . ["responseStatus:protected"]=> string(17) "Moved Temporarily" ["responseCode:protected"]=> int(302) ["httpVersion:protected"]=> float(1.1) ["headers:protected"]=> array(8) { ["Location"]=> string(91) "http://www.google.com/calendar/feeds/default/private/full?gsessionid=ulqFh1tY96KwH2uR8QBKYw" ["Content-Type"]=> string(24) "text/html; charset=UTF-8" ["Date"]=> string(29) "Sat, 17 May 2008 17:04:23 GMT" ["Expires"]=> string(29) "Sat, 17 May 2008 17:04:23 GMT" ["Cache-Control"]=> string(18) "private, max-age=0" ["Content-Length"]=> . . .

    46

    http://www.google.com/calendar/feeds/default/private/full?gsessionid=ulqFh1tY96KwH2uR8QBKYwhttp://www.google.com/calendar/feeds/default/private/full?gsessionid=ulqFh1tY96KwH2uR8QBKYwhttp://www.google.com/calendar/feeds/default/private/full?gsessionid=ulqFh1tY96KwH2uR8QBKYwhttp://www.google.com/calendar/feeds/default/private/full?gsessionid=ulqFh1tY96KwH2uR8QBKYw

  • Fixed The URL

    $url = 'http://www.google.com/calendar/feeds/default/private/full?gsessionid=ulqFh1tY96KwH2uR8QBKYw';

    $req = new HttpRequest($url, HttpRequest::METH_POST);

    $req->setBody($myentry);

    $req->setContentType('application/atom+xml');$req->setOptions(array('redirect'=>3));

    $req->addHeaders(array('Authorization' => "GoogleLogin auth=$token"));

    $msg = $req->send();

    echo $msg->getBody();

    47

    http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full'http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full'http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full'http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full'

  • Our New Entry

    http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/ns4d6037c1kvrm4i5ena2oo9h4 Cocktails Mashery sponsored cocktails... ...

    48

    http://www.w3.org/2005/Atomhttp://www.w3.org/2005/Atomhttp://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://www.google.com/calendar/feeds/cdatazone.org%40gmail.com/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://schemas.google.com/g/2005#event.organizerhttp://schemas.google.com/g/2005#event.organizermailto:[email protected]:[email protected]

  • Our Calendar

    49

  • Fix The Content, Time & Location

    $url = 'http://www.google.com/calendar/feeds/default/private/full? start-min=2008-05-22&start-max=2008-05-23&q=Cocktails';$req = new HttpRequest($url, HttpRequest::METH_GET);$req->setContentType('application/atom+xml');$req->setOptions(array('redirect'=>3));$req->addHeaders(array('Authorization' => "GoogleLogin auth=$token"));$msg = $req->send();

    if ($cal = simplexml_load_string( $msg->getBody() )) { foreach ($cal->entry AS $entry) { if ($entry->title == 'Cocktails') { $domentry = dom_import_simplexml($entry); $dom = new DOMDocument(); $myEntry = $dom->importNode($domentry, TRUE); $dom->appendChild($myEntry); } }}

    50

    http://www.google.com/calendar/feeds/default/private/full?start-min=2008-05-21T00:00:00&start-max=2008-05-21T23:59:59&q=Cocktails'http://www.google.com/calendar/feeds/default/private/full?start-min=2008-05-21T00:00:00&start-max=2008-05-21T23:59:59&q=Cocktails'http://www.google.com/calendar/feeds/default/private/full?start-min=2008-05-21T00:00:00&start-max=2008-05-21T23:59:59&q=Cocktails'http://www.google.com/calendar/feeds/default/private/full?start-min=2008-05-21T00:00:00&start-max=2008-05-21T23:59:59&q=Cocktails'

  • What Did We Find? (Summarized)

    http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4 Cocktails Mashery sponsored cocktails

    51

    http://www.w3.org/2005/Atomhttp://www.w3.org/2005/Atomhttp://schemas.google.com/g/2005http://schemas.google.com/g/2005http://schemas.google.com/g/2005http://schemas.google.com/g/2005http://schemas.google.com/gCal/2005http://schemas.google.com/gCal/2005http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478mailto:[email protected]:[email protected]://schemas.google.com/g/2005#event.organizerhttp://schemas.google.com/g/2005#event.organizermailto:[email protected]:[email protected]

  • Edit The Entry

    $gSession = '?gsessionid=3IqBQirtNrir7o4nNTCSDA';$gdNS = 'http://schemas.google.com/g/2005';

    $entry = simplexml_import_dom($dom);$entry->content = 'Mashery cocktail event';

    $when = $entry->children($gdNS)->when->attributes();$when['startTime'] = '2008-05-22T17:30:00.000-05:00';$when['endTime'] = '2008-05-22T19:30:00.000-05:00';

    $where = $entry->children($gdNS)->where->attributes();$where['valueString'] = '11th Floor';

    foreach ($entry->link AS $link) { if ($link['rel'] == 'edit') { $updateUrl = $link['href'] . $gSession; $contentType = $link['type']; }}

    52

    http://schemas.google.com/g/2005'http://schemas.google.com/g/2005'

  • Edited Entry (Summarized)

    http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4 Cocktails Mashery cocktail event

    53

    http://www.w3.org/2005/Atomhttp://www.w3.org/2005/Atomhttp://schemas.google.com/g/2005http://schemas.google.com/g/2005http://schemas.google.com/g/2005http://schemas.google.com/g/2005http://schemas.google.com/gCal/2005http://schemas.google.com/gCal/2005http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478http://www.google.com/calendar/feeds/default/private/full/ns4d6037c1kvrm4i5ena2oo9h4/63346727478mailto:[email protected]:[email protected]://schemas.google.com/g/2005#event.organizerhttp://schemas.google.com/g/2005#event.organizermailto:[email protected]:[email protected]

  • Call The Update

    $req = new HttpRequest($updateUrl, HttpRequest::METH_PUT);

    $req->setPutData($entry->asXML());$req->setContentType($contentType);

    $req->setOptions(array('redirect'=>3));

    $req->addHeaders(array('Authorization' => "GoogleLogin auth=$token"));$msg = $req->send();

    echo $msg->getBody();

    54

  • Updated Calendar

    55

  • Working With SOAP

  • • Web Service Inspection– WSDL Inspector

    – HTTP data inspection (request & response)

    • Web Service Invocation– Automatic Request generation

    – Authentication support (Basic, Digest, WS-Security)

    – Custom HTTP Header support

    • Web Service Development and Validation

    • Web Service Functional Testing

    • Web Service Load Testing

    • Web Service Simulation

    soapUI Features

    57

  • Working With soapUI

    58

  • Eclipse WSDL Editing

    59

  • Eclipse WSDL Editing

    60

  • Eclipse XML Schema Editing

    61

  • OpenCalais Service

    • http://www.opencalais.com/

    • Powered by Reuters

    • Extracts semantic metadata from documents

    • Results returned in RDF (Resource Description Framework) format

    • Become part of the Semantic Web

    • Service is Free!

    62

    http://www.opencalais.comhttp://www.opencalais.com

  • Inspect The API

    $wsdl = 'http://api.opencalais.com/enlighten/?wsdl';

    $client = new SOAPClient($wsdl);

    $types = $client->__getTypes();foreach ($types AS $type) { echo $type."\n";}echo "\n\n";

    $functions = $client->__getFunctions();foreach ($functions AS $func) { echo $func."\n";}

    63

    http://api.opencalais.com/enlighten/?wsdl'http://api.opencalais.com/enlighten/?wsdl'

  • OpenCalais API

    struct Enlighten { string licenseID; string content; string paramsXML;}struct EnlightenResponse { string EnlightenResult;}

    EnlightenResponse Enlighten(Enlighten $parameters)string Enlighten(string $licenseID, string $content, string $paramsXML)

    64

  • Working With Structs

    From WSDLstruct Enlighten { string licenseID; string content; string paramsXML;}

    IN PHP

    array('licenseID' => x, 'content' => y, 'paramsXML'=>z)

    class Enlighten { public $licenseID; public $content; public $paramsXML;}

    65

  • Making The Request

    $_content =

  • Making The Request

    $_ paramsXML =

  • Making The Request

    $wsdl = 'http://api.opencalais.com/enlighten/?wsdl';

    $client = new SOAPClient($wsdl);

    $result = $client->Enlighten( array( 'licenseID' => '', 'content' => $_content, 'paramsXML' => $_paramsXML ));

    echo $result->EnlightenResult;

    68

    http://api.opencalais.com/enlighten/?wsdl'http://api.opencalais.com/enlighten/?wsdl'

  • The Response (Edited)

    ... Norman Mineta political

    [the current system," Transportation Secretary ]Norman Mineta[ said in a statement. The newly ratified accord] 1765 13 ...

    69

    http://www.w3.org/1999/02/22-rdf-syntax-ns#http://www.w3.org/1999/02/22-rdf-syntax-ns#http://s.opencalais.com/1/pred/http://s.opencalais.com/1/pred/http://d.opencalais.com/pershash-1/37225f05-d55e-3512-9808-4ff11370db12http://d.opencalais.com/pershash-1/37225f05-d55e-3512-9808-4ff11370db12http://s.opencalais.com/1/type/em/e/Personhttp://s.opencalais.com/1/type/em/e/Personhttp://d.opencalais.com/dochash-1/11af6c89-9a70-331e-b113-12546ced5d10/Instance/1http://d.opencalais.com/dochash-1/11af6c89-9a70-331e-b113-12546ced5d10/Instance/1http://s.opencalais.com/1/type/sys/InstanceInfohttp://s.opencalais.com/1/type/sys/InstanceInfohttp://d.opencalais.com/dochash-1/11af6c89-9a70-331e-b113-12546ced5d10http://d.opencalais.com/dochash-1/11af6c89-9a70-331e-b113-12546ced5d10http://d.opencalais.com/pershash-1/37225f05-d55e-3512-9808-4ff11370db12http://d.opencalais.com/pershash-1/37225f05-d55e-3512-9808-4ff11370db12

  • What About the Other Method Signature?

    $wsdl = 'http://api.opencalais.com/enlighten/?wsdl';

    try {

    $client = new SOAPClient($wsdl);

    $result = $client->Enlighten('', $_content,

    $_paramsXML);

    echo $result->EnlightenResult;

    } catch (Exception $e) {

    echo "Fault: " . $e->faultstring."\n";

    echo "Code: " . $e->faultcode."\n";

    }

    70

    http://api.opencalais.com/enlighten/?wsdl'http://api.opencalais.com/enlighten/?wsdl'

  • When Things Go Wrong...

    Fault: ForbiddenCode: HTTP

    71

  • Enter Debug Mode

    $wsdl = 'http://api.opencalais.com/enlighten/?wsdl';

    $options = array('trace' => 1);

    try { $client = new SOAPClient($wsdl, $options);

    $result = $client->Enlighten('', $_content, $_paramsXML); echo $result->EnlightenResult;} catch (Exception $e) {

    echo $client->__getLastRequest();

    }

    72

  • Our Request

    NEWS

    http://biz.yahoo.com/rb/030905/airlines_damages_1.html

    ...

    73

    http://schemas.xmlsoap.org/soap/envelope/http://schemas.xmlsoap.org/soap/envelope/http://schemas.xmlsoap.org/soap/envelope/http://schemas.xmlsoap.org/soap/envelope/http://clearforest.comhttp://clearforest.comhttp://biz.yahoo.com/rb/030905/airlines_damages_1.htmlhttp://biz.yahoo.com/rb/030905/airlines_damages_1.htmlhttp://biz.yahoo.com/rb/030905/airlines_damages_1.htmlhttp://biz.yahoo.com/rb/030905/airlines_damages_1.htmlhttp://s.opencalais.com/1/pred/http://s.opencalais.com/1/pred/http://s.opencalais.com/1/pred/http://s.opencalais.com/1/pred/

  • Let’s Try soapUI

    74

  • Other Debugging Functions

    SOAPClient::__getLastRequest()– Get the raw SOAP request

    SOAPClient::__getLastRequestHeaders()– Get the HTTP headers sent with the request

    SOAPClient::__getLastResponse()– Get the response from the server

    SOAPClient::__getLAstResponseHeaders()– Get the HTTP headers received from the server

    75

  • Server Sided SOAP

  • DISABLE WSDL CACHINGWHEN DEVELOPING!

    ini_set("soap.wsdl_cache_enabled", "0");

    Disable That Cache

    77

  • Generating The WSDL

    • Integrated Generators– Services_Webservices

    • http://pear.php.net/package/Services_Webservice

    – PRADO

    • http://pradosoft.com/demos/quickstart/?page=Services.SoapService

    – WSO2 WSF/PHP (http://wso2.org/projects/wsf/php)

    • External Tools– Eclipse WSDL Editor in Web Tools Platform (WTP)

    – Zend Studio (http://www.zend.com/en/products/studio/)

    78

    http://pear.php.net/package/Services_Webservicehttp://pear.php.net/package/Services_Webservicehttp://pradosoft.com/demos/quickstart/?page=Services.SoapServicehttp://pradosoft.com/demos/quickstart/?page=Services.SoapServicehttp://wso2.org/projects/wsf/phphttp://wso2.org/projects/wsf/phphttp://www.zend.com/en/products/studio/http://www.zend.com/en/products/studio/

  • Services_Webservice WSDL Generation

    include_once('Services/Webservice.php'); class myService extends Services_Webservice { /** * Says "Hello!" * * @param int * @return string */ public function hello($i ) { //create some logic here return 'myString'; }

    79

  • Serving Up The WSDL

    Server Script: myserv.php

    /* Helper functions here */$soapSrv = new SoapServer('helloworld.wsdl');

    /* Register functions */$soapSrv->handle();

    Using the SoapClient:$soapClient = new SoapClient( 'http://localhost/myserv.php?wsdl');

    80

  • Handling Requests

    • The typical method to process a SOAP request– $soapServer->handle();

    • Request may be passed to handler– $soapServer->handle($request);

    • Passing in the request can be handy– You can be guaranteed of the same request while debugging

    – Debugging can be performed via CLI

    – Requests can be modified prior to being processed

    81

  • Handling Requests: Debugging

    /* create the initial request to be re-used */$request = file_get_contents("php://input");file_save_contents('debugging.xml', $request);

    /* retrieve saved request on subsequent calls$request = file_get_contents('debugging.xml');*/

    $server = new SoapServer($wsdl);/* Setup function handlers */$server->handle($request);

    82

  • Creating Our Service

  • class cSayHello { private $date = NULL;

    function __construct($date) { $this->_date = $date; }

    function greet($name, $age) { return "Hello $name. Today is" . $this->_date . ". You are $age"; }}

    Our Logic

    84

  • Skeleton Server

    ini_set("soap.wsdl_cache_enabled", "0");class cSayHello { private $date = NULL;

    function __construct($date) { $this->_date = $date; }

    function greet($name, $age) { return "Hello $name. Today is" . $this->_date . ". You are $age"; }}

    $srv = new SOAPServer();$srv->setClass('cSayHello', date());

    $srv->handle();

    85

  • Create The WSDL

    86

  • Creating The WSDL

    87

  • Creating The WSDL

    88

  • Calling The Client

    PHP Fatal error: Uncaught SoapFault exception: [Client] looks like we got no XML document in /Users/rrichards/Sites/fizzer/tek/PHPTek/demo/soapclient-step1.php:4Stack trace:#0 [internal function]: SoapClient->__call('greet', Array)#1 /Users/rrichards/Sites/fizzer/tek/PHPTek/demo/soapclient-step1.php(4): SoapClient->greet(Array)#2 {main} thrown in /Users/rrichards/Sites/fizzer/tek/PHPTek/demo/soapclient-step1.php on line 4

    89

  • Debugging The Server

    ini_set("soap.wsdl_cache_enabled", "0");

    //file_put_contents('/tmp/myclient.xml', file_get_contents('php://input'));$input = file_get_contents('/tmp/myclient.xml');class cSayHello { private $date = NULL;

    function __construct($date) { $this->_date = $date; }

    function greet($name, $age) { return "Hello $name. Today is" . $this->_date . ". You are $age"; }}

    $srv = new SOAPServer('myservice.wsdl');$srv->setClass('cSayHello', date());

    $srv->handle($input);

    90

  • Execute The Server Code

    PHP Warning: date() expects at least 1 parameter, 0 given in /Users/rrichards/Sites/fizzer/tek/PHPTek/demo/soapsrv.php on line 23

    PHP Warning: Missing argument 2 for cSayHello::greet() in /Users/rrichards/Sites/fizzer/tek/PHPTek/demo/soapsrv.php on line 15

    91

  • Fix Server Code

    ini_set("soap.wsdl_cache_enabled", "0");$input = file_get_contents('/tmp/mysoapclient.xml');

    class cSayHello { private $date = NULL;

    function __construct($date) { $this->_date = $date; }

    function greet($objGreet) { return "Hello $objGreet->name. Today is" . $this->_date . ". You are $objGreet->age"; }}

    $srv = new SOAPServer('myservice.wsdl');$srv->setClass('cSayHello', date('F j, Y'));

    $srv->handle($input);

    92

  • The Server Response

    Hello Rob. Today isMay 18, 2008. You are 37

    93

    http://schemas.xmlsoap.org/soap/envelope/http://schemas.xmlsoap.org/soap/envelope/

  • Service Component Architecture (SCA)

  • • Project by the Open Service Oriented Architecture (OSOA) collaboration - http://www.osoa.org/display/Main/Home

    • http://www.osoa.org/display/PHP/SOA+PHP+Homepage

    • Combined with the SDO extension

    • Pecl repository: http://pecl.php.net/package/SCA_SDO

    • Allows the developer to concentrate on the business logic rather than how it is all connected together

    Service Component Architecture (SCA)

    95

    http://www.osoa.org/display/Main/Homehttp://www.osoa.org/display/Main/Homehttp://www.osoa.org/display/PHP/SOA+PHP+Homepagehttp://www.osoa.org/display/PHP/SOA+PHP+Homepagehttp://pecl.php.net/package/SCA_SDOhttp://pecl.php.net/package/SCA_SDO

  • SCA Benefits

    • Support multiple protocols without additional coding

    • Re-usable code through the separation of business logic and communication layers

    • Local and remote integration transparency

    • Simplify consumption and exposure of web services

    96

  • SCA Components

    97

    BusinessLogic

    Annotations

    Binding Types

    Data Types

    InterfaceDescription

    SOAP Request

    JSON Request

    REST Request

    Developer’sResponsibility

  • SCA Component

    include "SCA/SCA.php";

    /** * @service * @binding.soap * @binding.jsonrpc * @binding.rest.rpc */

    class RobsService {

    /** Find out who I am. * @return string Who I am. */ public function whoAmI() { return "I am Rob Richards"; } }

    98

  • Calling The Component

    include "SCA/SCA.php"; $url = 'http://localhost/robsService.php';

    /* Use SOAP Binding */ $robservice = SCA::getService($url.'?wsdl'); $whoami = $robservice->whoAmI();

    /* Use JSON Binding */ $robservice = SCA::getService($url.'?smd'); $whoami = $robservice->whoAmI();

    /* Use Native SOAP */ $client = new SoapClient($url.'?wsdl'); $whoami = $client->whoAmI();

    /* Use RESTful Call */ $whoami = file_get_contents($url.'/whoAmI');

    /* Use Local Binding */ $robservice = SCA::getService('/home/rrichards/robweb/robsService.php'); $whoami = $robservice->whoAmI();

    99

    http://localhost/robsService.php'http://localhost/robsService.php'

  • Complex Types

    include "SCA/SCA.php";

    /** * @service * @binding.soap * @binding.jsonrpc * @types urn::people PeopleTypes.xsd*/

    100

  • Complex Types

    101

    http://www.w3.org/2001/XMLSchemahttp://www.w3.org/2001/XMLSchema

  • Creating The XML Schema

    102

  • Creating The XML Schema

    103

  • Finishing Off The Component

    class ComplexService {

    /** Find out who I am. * @param int $id My ID * @return PersonType urn::people Who I am. */ public function whoAmI($id) { $person = SCA::createDataObject('urn::people', 'PersonType'); $person->Name = 'Rob Richards'; $person->ID = $id; $person->TimeStamp = time(); return $person; } }

    104

  • Calling The Component

    $url = 'http://fizzer/tek/PHPTek/SCA/ComplexService.php';

    $complexservice = SCA::getService($url.'?wsdl'); $whoami = $complexservice->whoAmI(12);

    var_dump($whoami);

    object(SDO_DataObjectImpl)#11 (3) { ["Name"]=> string(12) "Rob Richards" ["ID"]=> string(2) "12" ["TimeStamp"]=> string(10) "1211136763"}

    105

    http://fizzer/tek/PHPTek/SCA/ComplexService.php'http://fizzer/tek/PHPTek/SCA/ComplexService.php'

  • Referencing Components

    class ReferenceService { /** * Get The WhoAmI from robsService * * @reference * @binding.php robsService.php */ public $robs_service;

    106

  • Referencing Components (cont’d)

    /** Find out who I am. * @param int $id My ID * @return PersonType urn::people Who I am. */ public function whoAmI($id) { $person = SCA::createDataObject('urn::people', 'PersonType'); $person->Name = $this->robs_service->whoAmI(); $person->ID = $id; $person->TimeStamp = time(); return $person; } }

    107

  • Calling New Component

    $url = 'http://fizzer/tek/PHPTek/SCA/ReferenceService.php';

    $referenceservice = SCA::getService($url.'?wsdl'); $whoami = $referenceservice->whoAmI(12);

    var_dump($whoami);

    object(SDO_DataObjectImpl)#16 (3) { ["Name"]=> string(17) "I am Rob Richards" ["ID"]=> string(2) "12" ["TimeStamp"]=> string(10) "1211136763"}

    108

    http://fizzer/tek/PHPTek/SCA/ReferenceService.php'http://fizzer/tek/PHPTek/SCA/ReferenceService.php'

  • SCA: More Information

    • Where To Get It– PECL package SCA_SDO

    – http://pecl.php.net/sca_sdo

    • Documentation, Wiki, Examples– PHP Manual SCA and SDO XML Data Access Service

    – Open Service Oriented Architecture http://www.osoa.org/display/PHP/

    • Mail List – http://groups.google.com/group/phpsoa

    109

    http://pecl.php.net/sca_sdohttp://pecl.php.net/sca_sdohttp://www.osoa.org/display/PHP/http://www.osoa.org/display/PHP/http://groups.google.com/group/phpsoahttp://groups.google.com/group/phpsoa

  • WSO2 Web Services Framework for PHP

    (WSO2 WSF/PHP)http://wso2.org/projects/wsf/php

    http://wso2.org/projects/wsf/phphttp://wso2.org/projects/wsf/php

  • • Web Service Provider and Consumer– SOAP

    – REST

    • WS-* Support– WS-Addressing

    – WS-Security / WS-SecurityPolicy

    – WS-ReliableMessaging

    • MTOM Support for attachments

    • WSDL Generation

    • PHP Class generation from WSDL

    WSO2 WSF/PHP

    111

  • Raw Request

    $client = new WSClient(array("to"=> "http://172.16.183.129/transpers.php"));

    $message =

  • WSDL Request

    $client = new WSClient(array("wsdl"=> "http://172.16.183.129/transformer.wsdl"));

    $proxy = $client->getProxy();

    $myperson = array('fname' => 'Joe', 'lname' => 'Schmoe');

    $res = $proxy->getPerson($myperson);var_dump($res);

    113

    http://172.16.183.129/transformer.wsdlhttp://172.16.183.129/transformer.wsdl

  • Raw Response

    function getPerson($message) { $sxe = simplexml_load_string($message->str);

    $response = “ {$sxe->fname} {$sxe->lname} ”.rand(18,100).”. ”.(rand(0,1)?'M':'F').” ”; return new WSMessage($response);}

    $soapSrv = new WSService(array("operations" => array("getPerson")));$soapSrv->reply();

    114

  • WSDL Response

    function getPersonfunc($fname, $lname) { return array('fullname' => $fname." ".$lname, 'age' => rand(18,100), 'sex' => (rand(0,1)?'M':'F'));}

    $operations = array("getPerson"=>"getPersonfunc");$opParams = array("getPersonfunc"=>"MIXED");

    $service = new WSService(array("wsdl"=>"transformer2.wsdl", "operations" => $operations, "opParams"=>$opParams)); $service->reply();

    115

  • REST

    $requestPayloadString = "myDemoPro PHP XML";

    try { $client = new WSClient( array("to"=>"http://search.yahooapis.com/WebSearchService/V1/webSearch", "HTTPMethod"=>GET, "useSOAP"=>FALSE));

    $responseMessage = $client->request($requestPayloadString); $results = simplexml_load_string($responseMessage->str);

    echo 'Total Results: '.$results['totalResultsAvailable']."\n\n";

    } catch (WSFault $e) { echo $e->Reason;}

    116

    http://search.yahooapis.com/WebSearchService/V1/webSearchhttp://search.yahooapis.com/WebSearchService/V1/webSearch

  • Advanced Usage

    $randNum = (rand()%99);

    $reqDate = mktime(0,0,0,date("m"),date("d")+14,date("Y"));$reqDateStr = date("Y/m/d", $reqDate); /* The payload string*/$requestPayloadString =

  • Attachments

    try { /* Load the design*/ $f = file_get_contents("./design.jpg"); /* Build the message*/ $requestMessage = new WSMessage($requestPayloadString, array("to" => "http://localhost/store/manuf_service.php", "action" => "http://www.back_packers.com/purchaseOrder", "attachments" => array("myid1" => $f)));

    118

    http://localhost/wsf/input.phphttp://localhost/wsf/input.phphttp://www.backhttp://www.back

  • Policy & WS-SecurityPolicy

    // Use WS-Policy File$policy_xml = file_get_contents("policy.xml");//$policy = new WSPolicy($policy_xml);

    // Use policy options$policy = new WSPolicy( array( "security" => array("encrypt"=>TRUE, "sign"=>TRUE, "algorithmSuite" => "Basic256Rsa15", "protectionOrder" => "EncryptBeforeSigning", "encryptSignature" => true, "includeTimeStamp" => true)));

    119

  • WS-SecurityPolicy

    120

  • WS-Security

    $rec_cert = ws_get_cert_from_file("bob_cert.cert"); $my_cert = ws_get_cert_from_file("alice_cert.cert"); $my_key = ws_get_key_from_file("alice_key.pem");

    /* Ceate a security token with reqd configurations*/ $sec_token = new WSSecurityToken(array("user" => "Alice", "password" => "abcd!1234", "passwordType" => "Digest", "privateKey" => $my_key, "certificate" => $my_cert, "receiverCertificate" => $rec_cert));

    121

  • Making The Request

    /* Create a new client*/ $client = new WSClient(array("useWSA" => TRUE, "useMTOM" => FALSE, "policy" => $policy, "securityToken" => $sec_token)); /* Request*/ $responseMessage = $client->request($requestMessage); /* Print the response*/ echo $responseMessage->str;

    } catch (WSFault $e) { echo $e->Reason;}

    122

  • Working With Web Services

    Rob Richards

    http://www.cdatazone.orghttp://xri.net/=rob.richards

    http://www.cdatazone.orghttp://www.cdatazone.orghttp://xri.net/=rob.richardshttp://xri.net/=rob.richards

  • We Are Hiring PHP & AJAX Developers Contact us: [email protected]

    OPEN TO ALL We want to meet you! Please join us for complimentary pizza

    and beer (or your drink of choice)

    Sheraton Gateway Suites O'Hare 11th floor

    Thursday, May 22nd 5:30 - 7:30pm

    mailto:[email protected]:[email protected]