1<<if: ZXIDBOOK>> 2<<else: >>ZXID ID-WSF API (SOAP Web Services) 3############### 4<<author: Sampo Kellom�ki (sampo@iki.fi)>> 5<<cvsid: $Id: zxid-wsf.pd,v 1.4 2010-01-08 02:10:09 sampo Exp $>> 6<<class: article!a4paper!!ZXID-WSF 01>> 7<<define: ZXDOC=ZXID Id-WSF API>> 8 9<<abstract: 10 11ZXID.org Identity Management toolkit implements standalone SAML 2.0 and 12Liberty ID-WSF 2.0 stacks. This document describes the API for making 13ID-WSF identity web services calls, i.e. SOAP calls. Discovery and 14providing a service are also covered. 15 16>> 17 18<<maketoc: 1>> 19 201 Introduction 21============== 22 23Here we describe the general philosophy of the ZXID ID-WSF 24APIs. Some function level documentation is available from 25<<link:../ref/html/index.html: Function reference>>. 26 271.1 Other documents 28------------------- 29 30<<doc-inc.pd>> 31<<htmlpreamble: <title>ZXID ID-WSF API (SOAP Web Services)</title><link type="text/css" rel=stylesheet href="zx.css"><body><h1>ZXID ID-WSF API (SOAP Web Services)</h1> >> 32 3313 ID-WSF Features of ZXID 34========================== 35 36<<fi: >> 37 3813.1 EPR Cache 39-------------- 40 41Calling an ID Web Service requires an Endpoint Reference (EPR) that 42indicates not only the URL of the web service, but also the security 43mechanism and any tokens or credentials required by the security 44mechanism, collectively called the +metadata+ of the EPR.<<footnote: 45While the role of the EPR metadata is broadly similar to SAML 46metadata, the two should not be confused.>> 47 48An EPR can be obtained from two sources 49 501. From the SSO assertion containing an attribute statement that 51 has the EPR. This is called the +bootstrap+ method. 52 532. By calling the discovery service. 54 55Either way, the EPRs are cached in the SSO session as files 56with paths like 57 58 /var/zxid/ses/SESID/SVCTYPE,SHA1 59 60where +SESID+ is the SSO session ID (safe base64 of a random number). 61+SVCTYPE+ and +SHA1+ form a unique file name inside the session directory. 62+SVCTYPE+ component allows easy identification of the EPRs that are 63relevant for calling a given service. The +SHA1+ component is a SHA1 hash 64over the canonical XML representation of the EPR. 65 66When bootstrap EPRs are present in the SSO assertion, they are 67automatically extracted to the EPR cache (internally 68zxid_snarf_eprs_from_ses() is called). Generally this will yield at 69least bootstrap EPR for discovery service. Later, when 70calling web services, discovery is automatically performed 71as needed and the results are automatically populated to the 72EPR cache (internally zxid_cache_epr() is called). 73 74When calling higher level WSC APIs, the discovery will happen 75automatically, but if you work in terms of lower level APIs, 76you can obtain an EPR by calling zxid_get_epr() which will 77first consult the cache, and if there is a miss, then try discovering 78the EPR using discovery service EPR, if any (usually one was obtained 79as bootstrap during the SSO). 80 8113.2 High level WSC API 82----------------------- 83 84The high level API is based on the idea of constructing 85the SOAP body (the payload) as a string and passing that 86to function that performs the SOAP call and returns 87response. 88 89 01 cf = zxid_new_conf_to_cf(CONF); 90 02 91 03 res = zxid_simple_cf(cf, cl, qs2, 0, 0x1fff); 92 04 switch (res[0]) { 93 05 default: 94 06 ERR("Unknown zxid_simple() response(%s)", res); 95 07 case 'd': break; /* Logged in case */ 96 08 } 97 09 sid = strstr(res, "sesid: "); 98 10 zxid_get_ses(cf, &sess, sid); 99 100 11 env = zxid_callf(cf, &sess, 0,0,0, zx_xmlns_idhrxml, 101 12 "<idhrxml:Modify>" 102 13 "<idhrxml:ModifyItem>" 103 14 "<idhrxml:Select>%s</idhrxml:Select>" 104 15 "<idhrxml:NewData>%s</idhrxml:NewData>" 105 16 "</idhrxml:ModifyItem>" 106 17 "</idhrxml:Modify>", cgi.select, cgi.data); 107 18 ZXID_CHK_STATUS(env, idhrxml_ModifyResponse, 108 19 hrxml_resp = "Modify failed"; break); 109 20 hrxml_resp = "Modify OK"; 110 111On lines 1-10 a single sign on is done to prepare the 112session and EPR cache. 113 11413.2.1 zxid_callf() - Make SOAP call with specified body 115~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 116 117 env = zxid_callf(cf, ses, svctype, url, di_opt, az_cred, fmt, ...) 118 119zxid_callf() first creates the body of the SOAP call 120by expanding the format string (which may involve additional 121arguments). Next it parses the string into XML data structure. 122If the format string uses unresolved namespaces, they are 123resolved using the svctype argument. 124 125Next zxid_callf() will attempt to locate an EPR for 126the service type. This may already be in cache, or 127discovery step may be performed. 128 129Then zxid_callf() augments the XML data structure with 130Liberty ID-WSF mandated headers. It will look at the 131security mechanism and token specified in the EPR and 132perform appropriate steps to create WS-Security header 133and apply signature as needed. 134 135Finally a SOAP call is made. The result is XML parsed 136and returned as SOAP envelope object. 137 138cf:: Configuration object, see zxid_new_conf_to_cf() 139ses:: Session object, used to locate EPRs, see zxid_get_ses() 140svctype:: Service type and namespace that is applicable 141 to the body. This is one of the constants from c/zx-ns.h 142url:: (Optional) If provided, this argument has to match either 143 the ProviderID, EntityID, or actual service endpoint URL. 144di_opt:: (Optional) Additional discovery options for selecting the 145 service, query string format 146az_cred:: (Optional) Additional authorization credentials or 147 attributes, query string format. These credentials will be populated 148 to the attribute pool in addition to the ones obtained from SSO and 149 other sources. Then a PDP is called to get an authorization decision 150 (as well as obligations we pledge to support). See also PEPMAP 151 configuration option. This implementes generalized (application 152 independent) Requestor Out and Requestor In PEPs. To implement 153 application dependent PEP features you should call zxid_az() directly. 154fmt:: printf style format string that is used to describe 155 the body of the call as a string. If fmt contains 156 format specifiers, then additional arguments 157 are used to expand these. 158 159Return value:: SOAP envelope as a string. 160 161> N.B. Although the request body is formulated as a string, 162> you can only use XML constructs whose schema is known to 163> ZXID. The resulting XML must be validly parseable by ZXID. 164 16513.2.2 ZXID_CHK_STATUS() - Macro for checking OK status 166~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 167 168 ZXID_CHK_STATUS(env, resp_tag, abort-action); 169 ZXID_CHK_STATUS(env, idhrxml_ModifyResponse, break); 170 171In ID-WSF web services it is very common that the overall 172outcome of the operation is expressed by <Status> element 173at top level. This macro makes it easy to check the status. 174 175If status is NOT "OK", then +abort-action+ is invoked. This 176would be whatever needed in your program to report error 177and abort further processing of the response. It could 178be a ~break~, ~return~, or even a ~goto~ statement. 179 180env:: SOAP envelope representing the response 181resp_tag:: The response tag as it appears as a child of env->Body 182abort-action:: Statement, or statements, used to report error and abort processing. 183 184There is no return value. This macro is "procedural". 185 18613.3 Low Level WSC API 187---------------------- 188 189Typical code for calling a web service at low level 190 191 01 #include <zx/errmac.h> 192 02 #include <zx/zxid.h> 193 03 #include <zx/zxidconf.h> 194 04 #include <zx/saml2.h> 195 05 #include <zx/wsf.h> 196 06 #include <zx/c/zx-ns.h> 197 07 198 08 struct zx_e_Envelope_s* env; 199 09 struct zx_a_EndpointReference_s* epr; 200 10 epr = zxid_get_epr(cf, ses, zx_xmlns_dap, 1); 201 11 if (epr) { 202 12 env = zx_NEW_e_Envelope(cf->ctx); 203 13 env->Header = zx_NEW_e_Header(cf->ctx); 204 14 env->Body = zx_NEW_e_Body(cf->ctx); 205 15 env->Body->Query = zxid_mk_dap_query(cf, ...); /* See ID-DAP inteface */ 206 16 env = zxid_wsc_call(cf, ses, epr, env); /* The beef */ 207 17 if (env->dap_QueryResponse) 208 18 D("Result is LDIF(%.*s)", 209 19 env->Body->dap_QueryResponse->Data->LDIF->gg.content->len, 210 20 env->Body->dap_QueryResponse->Data->LDIF->gg.content->s); 211 21 } 212 2131. On line 10 zxid_get_epr() is used with following arguments 214 cf:: Configuration object 215 ses:: Session object (generallly obtained from SSO) 216 zx_xmlns_dap:: The +service type+ of the service that is 217 to be called. Generally this is same as the namespace 218 URI. The include <zx/c/zx-ns.h> contains macros, 219 such as ~zx_xmlns_dap~, for the namespaces supported 220 by zxid. Alternatively you could simply supply the string. 221 1:: The last argument ("1", one) is an iterator index that, in case of 222 multiple EPRs allows you to pick which one to use. 223 Most common usage is to simply supply 1 which picks 224 the first one.<<footnote: However, the ordering of the 225 eprs in not currently well defined and may change 226 from one version of ZXID to another.>> 227 22813.3.1 zxid_get_epr() - Obtain EPR fron cache or by discovery 229~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 230 231 epr = zxid_get_epr(cf, ses, svctype, n); 232 233See if an EPR for service +svctype+ is available 234in current session EPR cache. If not, see if discovery 235EPR is available and try to discover the EPR for 236the +svctype+. Note that the discovery is transparent 237to the programmer - indeed programmer can not know 238whether EPR was served from cache (where it may have 239appeared by virtue of a bootstrap) or whether it 240was discovered. 241 242cf:: Configuration object, see zxid_new_conf_to_cf() 243ses:: Session object, used to locate EPRs in cache, see zxid_get_ses() 244svctype:: Service type (usually namespace of the service). 245 This is one of the constants from c/zx-ns.h 246n:: Ordinal. If more than one EPR is available, specifies 247 which one is desired. Usually 1 is supplied, to pick the first EPR. 248 249Return Value:: An EPR object (URL of the service, security mechanism, 250 and possibly security token (SAML assertion)). 251 252See also:: zxid_get_epr_address() for extracting URL as a string 253 25413.4 ID-DAP Interface 255--------------------- 256 257The ID-DAP search filters and data model are very similar to 258LDAP, see [RFC2251] for further explanation. 259 26013.4.1 Short example of using low level API 261~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 262 263 env->Body->dap_Query 264 = zxid_mk_dap_query(cf, 265 0, /* No tests */ 266 zxid_mk_dap_query_item(cf, 267 zxid_mk_dap_select(cf, 268 0, /* DN from ID-WSF */ 269 "objecttype=svcprofile", 270 0, /* all attributes */ 271 1, /* chase symlinks */ 272 ZXID_DAP_SCOPE_SUBTREE, 273 0, /* no size limit */ 274 0, /* no time limit */ 275 0), /* return data */ 276 0, /* regular data entries */ 277 0, /* No predefined operation */ 278 0, /* No sorting. */ 279 0, /* No changed since specification. */ 280 0, /* Do not include LDAP common attributes. */ 281 0, /* Start from first result (offset == 0) */ 282 0, /* Return all results (count == 0) */ 283 0, /* Do not request snapshot */ 284 0, /* Do not refer to snapshot */ 285 0), /* No contingent item ID reference */ 286 0); /* No subscriptions */ 287 288As can be seen, it is common to specify nearly all arguments as 0, 289relying on default values. Thus the code typically appears 290without comments as 291 292 env->Body->dap_Query 293 = zxid_mk_dap_query(cf, 0, 294 zxid_mk_dap_query_item(cf, 295 zxid_mk_dap_select(cf, 0, "objecttype=svcprofile", 296 0, 1, ZXID_DAP_SCOPE_SUBTREE, 0, 0, 0), 297 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), /* 10 zeroes here */ 298 0); /* No subscriptions */ 299 300 30113.4.2 Fully winded example of using low level API 302~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 303 304As a query can also have test and subscription clauses, the 305fully winded example becomes quite onerous. Of course for many 306daily tasks you will not need all the frills, or you can 307just use the simple API instead. 308 309 env->Body->dap_Query 310 = zxid_mk_dap_query(cf, 311 zxid_mk_dap_test_item(cf, 312 zxid_mk_dap_testop(cf, 313 0, /* DN from ID-WSF */ 314 "objecttype=svcprofile", 315 0, /* all attributes */ 316 1, /* chase symlinks */ 317 ZXID_DAP_SCOPE_SUBTREE, 318 0, /* no size limit */ 319 0, /* no time limit */ 320 0), /* return data */ 321 0, /* regular data entries */ 322 0), /* No predefined operation */ 323 zxid_mk_dap_query_item(cf, 324 zxid_mk_dap_select(cf, 325 0, /* DN from ID-WSF */ 326 "objecttype=svcprofile", 327 0, /* all attributes */ 328 1, /* chase symlinks */ 329 ZXID_DAP_SCOPE_SUBTREE, 330 0, /* no size limit */ 331 0, /* no time limit */ 332 0), /* return data */ 333 0, /* regular data entries */ 334 0, /* No predefined operation */ 335 0, /* No sorting. */ 336 0, /* No changed since specification. */ 337 0, /* Do not include LDAP common attributes. */ 338 0, /* Start from first result (offset == 0) */ 339 0, /* Return all results (count == 0) */ 340 0, /* Do not request snapshot */ 341 0, /* Do not refer to snapshot */ 342 0), /* No contingent item ID reference */ 343 zxid_mk_dap_subscription(cf, 344 "subsID", 345 0, /* No item ID reference */ 346 zxid_mk_dap_resquery(cf, 347 zxid_mk_dap_select(cf, 348 0, /* DN from ID-WSF */ 349 "objecttype=svcprofile", 350 0, /* all attributes */ 351 1, /* chase symlinks */ 352 ZXID_DAP_SCOPE_SUBTREE, 353 0, /* no size limit */ 354 0, /* no time limit */ 355 0), /* return data */ 356 0, /* regular data entries */ 357 0, /* No predefined operation */ 358 0, /* No sorting. */ 359 0, /* No changed since specification. */ 360 0, /* Do not include LDAP common attributes. */ 361 0), /* No contingent item ID reference */ 362 0, /* No notification aggregation spec. */ 363 0, /* No notification trigger spec. */ 364 0, /* Subscription starts immediately. */ 365 0, /* Subscription never expires. */ 366 1, /* Include changed data in the notifications. */ 367 0, /* Use notification reference for administrative notifications. */ 368 "http://host/notif_sink") 369 ); 370 37113.4.3 zxid_mk_dap_query() 372~~~~~~~~~~~~~~~~~~~~~~~~~~ 373 374 struct zx_dap_Query_s* zxid_mk_dap_query(struct zxid_conf* cf, 375 struct zx_dap_TestItem_s* tis, 376 struct zx_dap_QueryItem_s* qis, 377 struct zx_dap_Subscription_s* subs); 378 37913.4.4 zxid_mk_dap_query_item() 380~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 381 382 struct zx_dap_QueryItem_s* zxid_mk_dap_query_item(struct zxid_conf* cf, 383 struct zx_dap_Select_s* sel, 384 char* objtype, 385 char* predef, 386 char* sort, 387 char* changed_since, 388 int incl_common_attrs, 389 int offset, 390 int count, 391 char* setreq, 392 char* setid, 393 char* contingent_itemidref); 394 395sel:: Selection expression, see zxid_mk_dap_select(). 396objtype:: Either "entry", or "_Subsciption". The former is used for 397 searching and manipulating the normal attribute data while the 398 latter is used for manipulating subscription objects. Specifying 399 NULL selects "entry". 400predef:: Predefined serverside operation identifier. This 401 is server dependent, but you can think of it as a stored procedure. 402 If you pass predef, it is common to leave sel and objtype 403 as NULL and vice versa, i.e. you should pass NULL as 404 predef unless you know your server to expect otherwise. 405sort:: String specifying sorting of the result set. See ID-DAP 406 specification for further details. N.B. Not all servers 407 support sorting. Pass NULL if you do not need sorting. 408changed_since:: LDAP date time string specifying that only 409 entries that have changed since specified moment 410 should be returned. 411incl_common_attrs:: If 1 (true), "common" LDAP attributes such 412 as modificationtime are included. If you do not need these 413 attributes you can save the server some work and also 414 some network transmission overhead by not requesting 415 these attributes, i.e. pass 0 (false). 416offset:: If search matches multiple entries, the zero based 417 index of the first entry to return. Pass 0 to get the 418 beginning of the result set. 419count:: Maximum number of entries to return in the response. 0 means return 420 all. +offset+ and +count+ allow pagination through large 421 result set. N.B. +count+ is very different from +sizelimit+ 422 that you may specify in zxid_mk_dap_select(). The latter 423 causes the actual backend search operation to abort or return 424 partial result set if the result would be too large and 425 is unsuitable for pagination. 426setreq:: Request creation of a result set snapshot for pagination. 427 N.B. It is possible to paginate through large result 428 set even without creating a snapshot, but the results 429 may be inconsistent because the underlying data may change 430 between queries that paginate through it. Creating 431 a snapshot avoids this problem. Whether pagination with 432 or without snapshot is cheaper depends on the backend 433 implementation. +setreq+ is specified on the first query 434 that referes to the snapshot. The subsequent queries 435 referring to the same snapshot will specify +setid+. The 436 two are mutually exclusive: if +setid+ is specified 437 the +setreq+ must be NULL. 438setid:: If you are paginating through a result set snapshot 439 created using +setreq+, then you must specify +setid+ 440 in subsequent queries that refer to same snapshot. 441 When specifying +setreq+, you muse leave +setid+ as NULL. 442contingent_itemidref:: A query item can be made contingent 443 on a test item, i.e. the query will only be made if the 444 test succeeded. If you want this, you must pass the 445 item ID of the test item here. Passing NULL means that 446 no such dependency exists. N.B. The server side 447 implementation of the tests may actually require a query 448 to be made anyway. 449 45013.4.5 zxid_mk_dap_select() 451~~~~~~~~~~~~~~~~~~~~~~~~~~~ 452 453 struct zx_dap_Select_s* zxid_mk_dap_select(struct zxid_conf* cf, 454 char* dn, 455 char* filter, 456 char* attributes, 457 int deref_aliases, 458 int scope, 459 int sizelimit, 460 int timelimit, 461 int typesonly); 462 463dn:: Distinguished or relative distinguished name. Since ID-DAP usually 464 uses the identity conveyed using ID-WSF headers to determine 465 the distinguished name, it is common to pass simply a NULL. 466filter:: LDAP filter to apply. NULL if none. 467attributes:: List of attributes to return. NULL means return all attributes. 468deref_aliases:: Boolean: whether the server should chase any 469 "symlinks", i.e. an entry may appear at some location as 470 an alias that is just a pointer to the real location of the entry. 471 This is usually what you want so pass 1 (true). 472scope:: The scope of the ID-DAP search. 473 ZXID_DAP_SCOPE_BASE (0):: Only what is pointed to by DN, e.g. one 474 entry. The default. 475 ZXID_DAP_SCOPE_SINGLE (1):: Single level of directory right under DN. 476 ZXID_DAP_SCOPE_SUBTREE (2):: Full subtree search under the DN. 477sizelimit:: Maximum number of entries to return. 0 means no limit. This 478 is intended to stop the server from accidentally performing 479 expensive queries. N.B. +sizelimit+ is different from +count+, 480 see zxid_mk_dap_query_item(), the latter is meant for pagination 481 of a large result set without aborting it. 482timelimit:: Maximum number of seconds to spend in the search. 0 means no limit. 483typesonly:: If true, only attribute names are returned, without their 484 values. This allows an existence test to be performed without 485 passing the values over the network. Usually you want the 486 values so you would pass 0 (false). 487 48813.4.6 zxid_mk_dap_test_item() 489~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 490 491 struct zx_dap_TestItem_s* zxid_mk_dap_test_item(struct zxid_conf* cf, 492 struct zx_dap_TestOp_s* tstop, 493 char* objtype, 494 char* predef); 495 496tstop:: See zxid_mk_dap_testop(). 497objtype:: See +objtype+ in zxid_mk_dap_query_item(). 498predef:: See +predef+ in zxid_mk_dap_query_item(). 499 50013.4.7 zxid_mk_dap_testop() 501~~~~~~~~~~~~~~~~~~~~~~~~~~~ 502 503 struct zx_dap_TestOp_s* zxid_mk_dap_testop(struct zxid_conf* cf, 504 char* dn, 505 char* filter, 506 char* attributes, 507 int deref_aliases, 508 int scope, 509 int sizelimit, 510 int timelimit, 511 int typesonly); 512 513See description of zxid_mk_dap_select(). For ID-DAP protocol the 514Select and TestOp are defined to be the same. However, this need not be 515the case for Data Services Template (DST) based services in 516general. Hence, the data types for Select and TestOp are different 517(although very similar) and two separate constructors are needed. 518 51913.4.8 zxid_mk_dap_subscription() 520~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 521 522 struct zx_dap_Subscription_s* zxid_mk_dap_subscription(struct zxid_conf* cf, 523 char* subsID, 524 char* itemidref, 525 struct zx_dap_ResultQuery_s* rq, 526 char* aggreg, 527 char* trig, 528 char* starts, 529 char* expires, 530 int incl_data, 531 char* admin_notif, 532 char* notify_ref); 533 534subsID:: Subscription ID 535itemidref:: When subscribing to data described by a query item, 536 create item, or modify item, the reference to the relevant item. 537 NULL if no such item exists, in which case +rq+ is usually specified. 538rq:: Result query that identifies the data of interest for the 539 subscription. See zxid_mk_dap_resquery(). Pass NULL if the 540 data is identified otherwise, e.g. via +itemidref+. 541aggreg:: Notification aggregation mode. Implementation dependent. Pass NULL. 542 Notification aggregation is an optimization where some notification 543 may be delayed a little so that it can be sent more optimally 544 in same message with other notifications that may happen a little 545 later. This functionality need not be supported by the backend 546 implementations. 547trig:: Implementation dependent notification triggers. Pass NULL. 548starts:: Start date time of the subscription. NULL means subscription 549 starts immediately. 550expires:: End data time of the subscription. NULL means the subscription 551 will not expire. 552incl_data:: If 1 (true), the notifications resulting from the 553 subscription will contain the changed data (push model). If 554 0 (false), the notification will just say that something changed, 555 but interested party will need to perform a separate query 556 to retrieve the data (pull model). 557admin_notif:: Administrative notification address. If NULL, the 558 +notify_ref+ will be used for administrative notifications 559 as well. 560notify_ref:: Notification address. 561 56213.4.9 zxid_mk_dap_resquery() 563~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 564 565 struct zx_dap_ResultQuery_s* zxid_mk_dap_resquery(struct zxid_conf* cf, 566 struct zx_dap_Select_s* sel, 567 char* objtype, 568 char* predef, 569 char* sort, 570 int incl_common_attr, 571 char* changed_since, 572 char* contingent_itemidref); 573 574See description of zxid_mk_dap_query_item(). 575 576 57713.5 ID Messaging Interface 578--------------------------- 579 58013.6 ID Geo Location Interface 581------------------------------ 582 58313.7 Contact Book Interface 584--------------------------- 585 58613.8 People Service Interface 587----------------------------- 588 58913.9 Interface to Conor's Demo Media Service 590-------------------------------------------- 591 59213.10 ID-SIS Data Service for HR-XML 593------------------------------------ 594 595HR-XML defines a XML document format that can be used for data 596interchange in the Human Resources world. The essence of HR-XML is to 597represent CV (Curriculum Vitae, a.k.a. Resume) in structured form. 598 599At the moment (June 2007) HR-XML does not define any standard way to 600pass these documents around. In CV 2007 conference organized by EIfE-L 601in Paris, an idea was canvassed: use Liberty Data Service to exchange 602HR-XML documents. I tried to implement such service during the 603conference, but only got it working at the air port after the 604conference. 605 606This service is a good example of how to apply ZXID to implement 607your own services. 608 609*Files* 610 611 sg/hr-xml-sampo.sg - A slightly modified version of HR-XML schema 612 sg/id-hrxml.sg - Liberty DST 2.1 based data service for HR-XML 613 zxidhrxmlwsc.c - Web Services Client for HR-XML 614 zxidhrxmlwsp.c - Web Services Provider for HR-XML 615 616*Running demo* 617 6181. Set up your /etc/hosts. At least you need sp1.zxidsp.org 619 and you may also need your IdPs domain name (e.g. idp.symdemo.com). 620 6212. Start your IdP and DS (not supplied with ZXID) 622 623 cd /opt/SYMfiam/std 624 conf/test-idp3/start.sh start log 625 626 Next you need to cause the id-hr-xml services to be registered 627 in the discovery service. This depends on product. (*** fix) 628 629 Then you need to create an association for id-hr-xml service 630 for some test user. 631 6323. Start the web services client 633 634 mini_httpd -p 8443 -c 'zxid*' -S -E zxid.pem -l tmp/mini.stderr & 635 tail -f tmp/zxid.stderr& 636 6374. Start the web services provider 638 639 mini_httpd -p 8444 -c 'zxid*' -S -E zxid.pem -l tmp/mini2.stderr & 640 tail -f tmp/zxid2.stderr& 641 6425. Start browsing from 643 644 https://sp1.zxidsp.org:8443/zxidhrxmlwsc?o=E 645 6466. Login using the test user that has the association 647 6487. Paste <Candidate> element in HR-XML Data form field and click Create. This 649 creates a Candidate record in the WSP. 650 6518. Click Query. This queries the WSP for the record we saved in previous step. 652 You should see the record appear in the HR-XML Response field. 653 654http://s-idp.liberty-iop.org:8881/N 655 656<<if: ZXIDBOOK>> 657<<else: >> 658 65996 License 660========== 661 662Copyright (c) 2006-2009 Symlabs (symlabs@symlabs.com), All Rights Reserved. 663Author: Sampo Kellom�ki (sampo@iki.fi) 664 665Licensed under the Apache License, Version 2.0 (the "License"); 666you may not use this file except in compliance with the License. 667You may obtain a copy of the License at 668http://www.apache.org/licenses/LICENSE-2.0 669 670Unless required by applicable law or agreed to in writing, software 671distributed under the License is distributed on an "AS IS" BASIS, 672WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 673See the License for the specific language governing permissions and 674limitations under the License. 675 67696.2 Specification IPR 677---------------------- 678 679ZXID is based on open SAML and Liberty specifications. The parties 680that have developed these specifications, including Symlabs, have made 681Royalty Free (RF) licensing commitment. Please ask OASIS and Liberty 682Alliance for the specifics of their IPR policies and IPR disclosures. 683 684Some protocols, such as WS-Trust and WS-Federation enjoy Microsoft's 685pledge<<footnote: If you have a reference to where this pledge can be 686found, please let me know so it can be included here.>> that they will 687not sue you even if you implement these specifications. You should 688evaluate yourself whether this is good enough for your situation. 689 690<<zxid-ref.pd>> 691<<doc-end.pd>> 692<<notapath: TCP/IP a.k.a xBSD/Unix n/a Perl/mod_perl PHP/mod_php Java/Tomcat>> 693<<EOF: >> 694<<fi: >>