001/** 002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 003 * 004 * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved 005 * 006 * The contents of this file are subject to the terms 007 * of the Common Development and Distribution License 008 * (the License). You may not use this file except in 009 * compliance with the License. 010 * 011 * You can obtain a copy of the License at 012 * https://opensso.dev.java.net/public/CDDLv1.0.html or 013 * opensso/legal/CDDLv1.0.txt 014 * See the License for the specific language governing 015 * permission and limitations under the License. 016 * 017 * When distributing Covered Code, include this CDDL 018 * Header Notice in each file and include the License file 019 * at opensso/legal/CDDLv1.0.txt. 020 * If applicable, add the following below the CDDL Header, 021 * with the fields enclosed by brackets [] replaced by 022 * your own identifying information: 023 * "Portions Copyrighted [year] [name of copyright owner]" 024 * 025 * $Id: DSTClient.java,v 1.5 2008/12/16 01:48:32 exu Exp $ 026 * 027 */ 028 029package com.sun.identity.liberty.ws.dst; 030 031import com.sun.identity.liberty.ws.security.SecurityAssertion; 032import com.sun.identity.liberty.ws.common.wsse.BinarySecurityToken; 033import com.sun.identity.liberty.ws.disco.EncryptedResourceID; 034import com.sun.identity.liberty.ws.disco.ResourceOffering; 035import com.sun.identity.liberty.ws.disco.ServiceInstance; 036import com.sun.identity.liberty.ws.disco.Description; 037import com.sun.identity.liberty.ws.disco.ResourceID; 038import com.sun.identity.liberty.ws.soapbinding.Message; 039import com.sun.identity.liberty.ws.soapbinding.Client; 040import com.sun.identity.liberty.ws.soapbinding.ProviderHeader; 041import com.sun.identity.liberty.ws.soapbinding.SOAPFaultException; 042import com.sun.identity.liberty.ws.soapbinding.SOAPBindingException; 043import java.util.List; 044import java.util.ArrayList; 045import java.util.Iterator; 046import org.w3c.dom.Element; 047import com.sun.identity.liberty.ws.security.SecurityTokenManagerClient; 048import com.sun.identity.liberty.ws.interaction.InteractionRedirectException; 049import com.sun.identity.liberty.ws.interaction.InteractionException; 050import com.sun.identity.liberty.ws.interaction.InteractionManager; 051import com.sun.identity.liberty.ws.soapbinding.ServiceInstanceUpdateHeader; 052import com.sun.identity.liberty.ws.soapbinding.SOAPBindingConstants; 053import com.sun.identity.liberty.ws.soapbinding.Utils; 054import com.sun.identity.shared.configuration.SystemPropertiesManager; 055import javax.servlet.http.HttpServletRequest; 056import javax.servlet.http.HttpServletResponse; 057 058/** 059 * The class <code>DSTClient</code> provides methods for Liberty 060 * Data Service Template. 061 * 062 * @supported.all.api 063 */ 064public class DSTClient { 065 066 private String resourceID = null; 067 private EncryptedResourceID encryptedResourceID = null; 068 private String soapURI = null; 069 private String certAlias = null; 070 private SecurityAssertion assertion = null; 071 private BinarySecurityToken token = null; 072 private boolean isEncryptedResourceID = false; 073 // default to anonymous 074 private int securityProfile = Message.ANONYMOUS; 075 private String soapAction = null; 076 private String serviceType = null; 077 private HttpServletRequest httpRequest = null; 078 private HttpServletResponse httpResponse = null; 079 private boolean clientAuthEnabled = false; 080 private String providerID = null; 081 private ServiceInstanceUpdateHeader serviceInstanceUpdateHeader = null; 082 private String wsfVersion = Utils.getDefaultWSFVersion(); 083 084 085 /** 086 * Constructor 087 * The constructor connects to Data Service without <code>WSS</code> token 088 * @param soapURI URI of the SOAP end point for this Data service 089 * instance 090 * @param providerID ID of service provider. 091 */ 092 public DSTClient(String soapURI, String providerID) { 093 this.soapURI = soapURI; 094 this.providerID = providerID; 095 this.securityProfile = Message.ANONYMOUS; 096 } 097 098 /** 099 * Constructor 100 * The constructor connects to Data Service using <code>WSS</code> 101 * SAML Token 102 * @param assertion <code>WSS</code> SAML Token 103 * @param soapURI URI of the SOAP end point for this data 104 * service instance 105 * @param providerID ID of service provider. 106 */ 107 public DSTClient (SecurityAssertion assertion, 108 String soapURI, 109 String providerID) { 110 this.assertion = assertion; 111 this.soapURI = soapURI; 112 this.providerID = providerID; 113 if(assertion != null && assertion.isBearer()) { 114 this.securityProfile = Message.BEARER_TOKEN; 115 } else { 116 this.securityProfile = Message.SAML_TOKEN; 117 } 118 } 119 120 /** 121 * Constructor 122 * The constructor connects to the data Service using <code>WSS X509</code> 123 * Token. 124 * 125 * @param token <code>WSS X.509</code> Certificate Token 126 * @param soapURI URI of the SOAP end point for this Data 127 * service instance 128 * @param providerID ID of service provider. 129 */ 130 public DSTClient(BinarySecurityToken token, 131 String soapURI, 132 String providerID) { 133 this.token = token; 134 this.soapURI = soapURI; 135 this.securityProfile = Message.X509_TOKEN; 136 this.providerID = providerID; 137 } 138 139 /** 140 * Constructor 141 * The constructor connects to Data Service without <code>WSS</code> token, 142 * the <code>HttpServletRequest</code> and <code>HttpServletResponse</code> 143 * object of the current request agent will be used for resource owner 144 * interactions if needed. 145 * 146 * @param soapURI URI of the SOAP end point for this Data 147 * service instance 148 * @param providerID ID of service provider. 149 * @param httpRequest <code>HttpServletRequest</code> object of current 150 * user agent request. 151 * @param httpResponse <code>HttpServletResponse</code> object of current 152 * user agent request. 153 */ 154 public DSTClient(String soapURI, 155 String providerID, 156 HttpServletRequest httpRequest, 157 HttpServletResponse httpResponse) { 158 this.soapURI = soapURI; 159 this.securityProfile = Message.ANONYMOUS; 160 this.httpRequest = httpRequest; 161 this.httpResponse = httpResponse; 162 this.providerID = providerID; 163 } 164 165 /** 166 * Constructor 167 * The constructor connects to Data Service with <code>WSS</code> 168 * SAML token, the <code>HttpServletRequest</code> and 169 * <code>HttpServletResponse</code> object of the current request 170 * agent will be used for resource owner interactions if needed. 171 * @param assertion <code>WSS</code> SAML Token. 172 * @param soapURI URI of the SOAP end point for this Data service instance. 173 * @param providerID ID of service provider. 174 * @param httpRequest <code>HttpServletRequest</code> object of current 175 * user agent request. 176 * @param httpResponse <code>HttpServletResponse</code> object of current 177 * user agent request. 178 */ 179 public DSTClient(SecurityAssertion assertion, 180 String soapURI, 181 String providerID, 182 HttpServletRequest httpRequest, 183 HttpServletResponse httpResponse) { 184 185 this.httpRequest = httpRequest; 186 this.httpResponse = httpResponse; 187 this.assertion = assertion; 188 this.soapURI = soapURI; 189 this.securityProfile = Message.SAML_TOKEN; 190 this.providerID = providerID; 191 } 192 193 /** 194 * Constructor 195 * The constructor connects to Data Service with <code>WSS</code> 196 * SAML token, the <code>HttpServletRequest</code> and 197 * <code>HttpServletResponse</code> object of the current request 198 * agent will be used for resource owner interactions if needed. 199 * @param token <code>WSS X.509</code> Certificate Token 200 * @param soapURI URI of the SOAP end point for this Data 201 * service instance 202 * @param providerID ID of service provider. 203 * @param httpRequest <code>HttpServletRequest</code> object of current 204 * user agent request. 205 * @param httpResponse <code>HttpServletResponse</code> object of current 206 * user agent. 207 */ 208 public DSTClient(BinarySecurityToken token, 209 String soapURI, 210 String providerID, 211 HttpServletRequest httpRequest, 212 HttpServletResponse httpResponse) { 213 this.token = token; 214 this.soapURI = soapURI; 215 this.securityProfile = Message.X509_TOKEN; 216 this.httpRequest = httpRequest; 217 this.httpResponse = httpResponse; 218 this.providerID = providerID; 219 } 220 221 /** 222 * Contructor 223 * Creates a data service template client instance. 224 * Connects to data Service specified by the resource offering. 225 * <code>resourceID</code>, security mechanism and SOAP endpoint defined 226 * in the <code>ResourceOffering</code> will be used. 227 * 228 * @param resourceOffering resource offering for this 229 * discovery service instance 230 * @param providerID ID of this service provider. 231 * @param credential Credential of <code>WSC</code> 232 * @param httpRequest <code>HttpServletRequest</code> object of current 233 * user agent request. 234 * @param httpResponse <code>HttpServletResponse</code> object of current 235 * user agent. 236 * @exception DSTException if the <code>resourceOffering</code> is not valid 237 */ 238 public DSTClient( 239 ResourceOffering resourceOffering, 240 String providerID, 241 Object credential, 242 HttpServletRequest httpRequest, 243 HttpServletResponse httpResponse 244 ) throws DSTException { 245 if(resourceOffering == null) { 246 DSTUtils.debug.error("DSTClient: resource offering is null"); 247 throw new DSTException( 248 DSTUtils.bundle.getString("nullInputParams")); 249 } 250 parseResourceOffering(resourceOffering); 251 if(securityProfile == Message.X509_TOKEN) { 252 generateBinarySecurityToken(credential); 253 } 254 this.httpRequest = httpRequest; 255 this.httpResponse = httpResponse; 256 this.providerID = providerID; 257 } 258 259 /** 260 * Constructor 261 * Creates a data service template client instance. 262 * Connects to data Service specified by the resource offering. 263 * <code>resourceID</code>, security mechanism and SOAP endpoint defined 264 * in the <code>ResourceOffering</code> will be used. 265 * 266 * @param resourceOffering resource offering for this 267 * discovery service instance 268 * @param providerID ID of this service provider. 269 * @param credential Credential of <code>WSC</code> 270 * @exception DSTException if the <code>resourceOffering</code> is not valid 271 */ 272 public DSTClient(ResourceOffering resourceOffering, 273 String providerID, 274 Object credential) 275 throws DSTException { 276 if(resourceOffering == null) { 277 DSTUtils.debug.error("DSTClient: resource offering is null"); 278 throw new DSTException(DSTUtils.bundle.getString("nullInputParams")); 279 } 280 parseResourceOffering(resourceOffering); 281 if(securityProfile == Message.X509_TOKEN) { 282 generateBinarySecurityToken(credential); 283 } 284 this.providerID = providerID; 285 } 286 287 /** 288 * Parses the given discovery resource offering for the Data service. 289 * @param offering ResourceOffering 290 * @exception DSTException. 291 */ 292 private void parseResourceOffering(ResourceOffering offering) 293 throws DSTException { 294 //Try for the encrypted resource offering first; 295 encryptedResourceID = offering.getEncryptedResourceID(); 296 if(encryptedResourceID != null) { 297 isEncryptedResourceID = true; 298 } else { 299 ResourceID resID = offering.getResourceID(); 300 if(resID == null) { 301 DSTUtils.debug.error("DSTClient:parseResourceOffering: " + 302 "No ResourceID"); 303 throw new DSTException(DSTUtils.bundle.getString("noResourceID")); 304 } 305 resourceID = resID.getResourceID(); 306 } 307 308 ServiceInstance serviceInstance = offering.getServiceInstance(); 309 // providerID = serviceInstance.getProviderID(); 310 if(serviceInstance == null) { 311 DSTUtils.debug.error("DSTClient:parseResourceOffering: " + 312 "No service instance."); 313 throw new DSTException( 314 DSTUtils.bundle.getString("noServiceInstance")); 315 } 316 serviceType = serviceInstance.getServiceType(); 317 if(serviceType == null) { 318 DSTUtils.debug.error("DSTClient:parseResourceOffering: " + 319 "service type is null."); 320 throw new DSTException(DSTUtils.bundle.getString("noServiceType")); 321 } 322 323 List descriptions = serviceInstance.getDescription(); 324 if(descriptions == null || descriptions.isEmpty()) { 325 DSTUtils.debug.error("DSTClient:parseResourceOffering: " + 326 "descriptions are null."); 327 throw new DSTException(DSTUtils.bundle.getString("noDescriptions")); 328 } 329 // A service instance can have mutiple descriptions. In this case, 330 // we will try to use a valid description. 331 Iterator iter = descriptions.iterator(); 332 while(iter.hasNext()) { 333 Description description = (Description)iter.next(); 334 soapAction = description.getSoapAction(); 335 soapURI = description.getEndpoint(); 336 if(soapURI == null || soapURI.length() == 0) { 337 continue; 338 } 339 340 List secMechIDs = description.getSecurityMechID(); 341 if(secMechIDs == null || secMechIDs.isEmpty()) { 342 continue; 343 } 344 boolean foundProfile = false; 345 int size = secMechIDs.size(); 346 347 for(int i=0; i < size; i++) { 348 String secProfile = (String)secMechIDs.get(i); 349 secProfile = secProfile.trim(); 350 351 if(secProfile.equals(Message.NULL_NULL) || 352 secProfile.equals(Message.TLS_NULL) || 353 secProfile.equals(Message.CLIENT_TLS_NULL)) { 354 355 securityProfile = Message.ANONYMOUS; 356 if(secProfile.equals(Message.CLIENT_TLS_NULL)) { 357 clientAuthEnabled = true; 358 } 359 foundProfile = true; 360 break; 361 362 } else if(secProfile.equals(Message.NULL_X509) || 363 secProfile.equals(Message.TLS_X509) || 364 secProfile.equals(Message.CLIENT_TLS_X509) || 365 secProfile.equals(Message.NULL_X509_WSF11) || 366 secProfile.equals(Message.TLS_X509_WSF11) || 367 secProfile.equals(Message.CLIENT_TLS_X509_WSF11)) { 368 369 securityProfile = Message.X509_TOKEN; 370 if (secProfile.equals(Message.NULL_X509) || 371 secProfile.equals(Message.TLS_X509) || 372 secProfile.equals(Message.CLIENT_TLS_X509)) { 373 wsfVersion = SOAPBindingConstants.WSF_10_VERSION; 374 } else { 375 wsfVersion = SOAPBindingConstants.WSF_11_VERSION; 376 } 377 378 securityProfile = Message.X509_TOKEN; 379 if (secProfile.equals(Message.CLIENT_TLS_X509) || 380 secProfile.equals(Message.CLIENT_TLS_X509_WSF11)) { 381 clientAuthEnabled = true; 382 } 383 foundProfile = true; 384 break; 385 386 } else if(secProfile.equals(Message.NULL_SAML) || 387 secProfile.equals(Message.TLS_SAML) || 388 secProfile.equals(Message.CLIENT_TLS_SAML) || 389 secProfile.equals(Message.NULL_SAML_WSF11) || 390 secProfile.equals(Message.TLS_SAML_WSF11) || 391 secProfile.equals(Message.CLIENT_TLS_SAML_WSF11)) { 392 393 securityProfile = Message.SAML_TOKEN; 394 if (secProfile.equals(Message.NULL_SAML) || 395 secProfile.equals(Message.TLS_SAML) || 396 secProfile.equals(Message.CLIENT_TLS_SAML)) { 397 wsfVersion = SOAPBindingConstants.WSF_10_VERSION; 398 } else { 399 wsfVersion = SOAPBindingConstants.WSF_11_VERSION; 400 } 401 if (secProfile.equals(Message.CLIENT_TLS_SAML) || 402 secProfile.equals(Message.CLIENT_TLS_SAML_WSF11)) { 403 clientAuthEnabled = true; 404 } 405 foundProfile = true; 406 break; 407 } else if(secProfile.equals(Message.NULL_BEARER) || 408 secProfile.equals(Message.TLS_BEARER) || 409 secProfile.equals(Message.CLIENT_TLS_BEARER) || 410 secProfile.equals(Message.NULL_BEARER_WSF11) || 411 secProfile.equals(Message.TLS_BEARER_WSF11) || 412 secProfile.equals(Message.CLIENT_TLS_BEARER_WSF11)) { 413 414 securityProfile = Message.BEARER_TOKEN; 415 if (secProfile.equals(Message.NULL_BEARER) || 416 secProfile.equals(Message.TLS_BEARER) || 417 secProfile.equals(Message.CLIENT_TLS_BEARER)) { 418 wsfVersion = SOAPBindingConstants.WSF_10_VERSION; 419 } else { 420 wsfVersion = SOAPBindingConstants.WSF_11_VERSION; 421 } 422 423 if (secProfile.equals(Message.CLIENT_TLS_BEARER) || 424 secProfile.equals(Message.CLIENT_TLS_BEARER_WSF11)) { 425 clientAuthEnabled = true; 426 } 427 foundProfile = true; 428 break; 429 } 430 431 } 432 if(foundProfile) { 433 break; 434 } 435 } 436 437 if(soapURI == null) { 438 DSTUtils.debug.error("DSTClient:parseResourceOffering: " + 439 "SOAP Endpoint or security profile is null"); 440 throw new DSTException( 441 DSTUtils.bundle.getString("invalidResourceOffering")); 442 } 443 if(DSTUtils.debug.messageEnabled()) { 444 DSTUtils.debug.message("DSTClient.parseResourceOffering:" + 445 "soapURI = " + soapURI + "soapAction = " + soapAction + 446 "securityProfile = " + securityProfile); 447 } 448 449 } 450 451 /** 452 * Generates X509 security token for the WSC. 453 * @param credential Credential of WSC 454 * @exception DSTException 455 */ 456 private void generateBinarySecurityToken(Object credential) 457 throws DSTException { 458 try { 459 SecurityTokenManagerClient manager = 460 new SecurityTokenManagerClient(credential); 461 if (certAlias == null) { 462 certAlias = SystemPropertiesManager.get( 463 "com.sun.identity.liberty.ws.wsc.certalias"); 464 } 465 manager.setCertAlias(certAlias); 466 token = manager.getX509CertificateToken(); 467 token.setWSFVersion(wsfVersion); 468 } catch (Exception e) { 469 DSTUtils.debug.error("DSTClient:generateBinarySecurityToken:" + 470 "Error in generating binary security token.", e); 471 throw new DSTException(e); 472 } 473 } 474 475 476 /** 477 * Sets the resource ID to be accessed 478 * @param resourceID resource ID String 479 */ 480 public void setResourceID(String resourceID) { 481 this.resourceID = resourceID; 482 isEncryptedResourceID = false; 483 } 484 485 /** 486 * Sets the encrypted resource ID to be accessed 487 * @param encResourceID encrypted resource ID 488 */ 489 public void setResourceID(EncryptedResourceID encResourceID) { 490 this.encryptedResourceID = encResourceID; 491 isEncryptedResourceID = true; 492 } 493 494 /** 495 * Sets the provider ID. 496 * @param providerID Provider ID. 497 */ 498 public void setProviderID(String providerID) { 499 this.providerID = providerID; 500 } 501 502 /** 503 * Sets the alias for the client certificate if the connection is TLS/SSL 504 * with client authentication. 505 * 506 * @param certAlias certificate alias name 507 */ 508 public void setClientCert(String certAlias) { 509 this.certAlias = certAlias; 510 } 511 512 /** 513 * Sets SOAP Action such as query or modify 514 * @param action action for this soap request 515 */ 516 public void setSOAPAction(String action) { 517 this.soapAction = action; 518 } 519 520 /** 521 * Sets the client authentication. 522 * 523 * @param value true value to enable client authentication. 524 */ 525 public void setClientAuth(boolean value) { 526 this.clientAuthEnabled = value; 527 } 528 529 /** 530 * Sets the SOAP Endpoint. 531 * @param endpoint SOAP Endpoint. 532 */ 533 public void setSOAPEndPoint(String endpoint) { 534 this.soapURI = endpoint; 535 } 536 537 /** 538 * Sets the Security Assertion. 539 * @param secAssertion Security Assertion. 540 */ 541 public void setSecurityAssertion(SecurityAssertion secAssertion) { 542 this.assertion = secAssertion; 543 } 544 545 /** 546 * Sets the binary security token. 547 * @param binaryToken Binary Security Token. 548 */ 549 public void setBinarySecurityToken(BinarySecurityToken binaryToken) { 550 this.token = binaryToken; 551 } 552 553 /** 554 * Sets the security mechanism. 555 * @param secMech security mechanism. 556 */ 557 public void setSecurityMech(String secMech) { 558 if(secMech == null || secMech.endsWith("null")) { 559 securityProfile = Message.ANONYMOUS; 560 } else if(secMech.endsWith("X509")) { 561 securityProfile = Message.X509_TOKEN; 562 } else if(secMech.endsWith("SAML")) { 563 securityProfile = Message.SAML_TOKEN; 564 } else if(secMech.endsWith("Bearer")) { 565 securityProfile = Message.BEARER_TOKEN; 566 } 567 } 568 569 570 /** 571 * Gets data for the specified query items. 572 * @param items list of <code>DSTQueryItem</code> object 573 * @return List of <code>DSTData</code> objects which have one-to-one 574 * correspondence to the list of query items. If no response for 575 * one of the query item, the corresponding return 576 * <code>DSTData</code> object will be null. 577 * @exception DSTException if error occurs when trying to get data 578 * @exception InteractionRedirectException if user agent is redirected to 579 * Web Service Provider (<code>WSP</code>) for resource owner 580 * interactions 581 */ 582 public java.util.List getData(java.util.List items) 583 throws DSTException, InteractionRedirectException 584 { 585 DSTUtils.debug.message("DSTClient:getData:Init"); 586 587 if(items == null || items.size() == 0) { 588 DSTUtils.debug.error("DSTUtils.getData:Query items are null."); 589 throw new DSTException(DSTUtils.bundle.getString("nullInputParams")); 590 } 591 592 DSTQuery dstQuery = null; 593 594 if(isEncryptedResourceID) { 595 dstQuery = new DSTQuery(encryptedResourceID, items, null); 596 } else { 597 dstQuery = new DSTQuery(resourceID, items, null); 598 } 599 600 List query = new ArrayList(); 601 query.add(DSTUtils.parseXML(dstQuery.toString(true, true))); 602 603 List response = sendMessage(query); 604 605 if(response == null || response.size() == 0) { 606 DSTUtils.debug.message("DSTClient:getData: response is null"); 607 return null; 608 } 609 610 DSTQueryResponse queryResponse = 611 new DSTQueryResponse((Element)response.get(0)); 612 return queryResponse.getData(); 613 } 614 615 /** 616 * Gets <code>QueryResponse</code> for the specified query. 617 * @param query <code>DSTQuery</code> object. 618 * @return <code>DSTDQueryResponse</code> Object. 619 * @exception DSTException if error occurs when trying to get data 620 * @exception InteractionRedirectException if user agent is redirected to 621 * Web Service Provider (<code>WSP</code>) for resource owner 622 * interactions 623 */ 624 public DSTQueryResponse query(DSTQuery query) 625 throws DSTException, InteractionRedirectException { 626 627 DSTUtils.debug.message("DSTClient:query:Init"); 628 if(query == null) { 629 DSTUtils.debug.message("DSTClient:query:null value"); 630 throw new DSTException(DSTUtils.bundle.getString("nullInputParams")); 631 } 632 633 List request = new ArrayList(); 634 request.add(DSTUtils.parseXML(query.toString(true, true))); 635 List response = sendMessage(request); 636 Element queryResponse = (Element)response.get(0); 637 return new DSTQueryResponse(queryResponse); 638 } 639 640 /** 641 * Gets response for a list of <code>DST</code> Modifications. 642 * @param items List of <code>DSTModification</code> objects. 643 * @return <code>DSTModifyResponse</code>. 644 * @exception DSTException if error occurs when trying to modify data 645 * @exception InteractionRedirectException if user agent is redirected to 646 * Web Service Provider (<code>WSP</code>) for resource owner 647 * interactions. 648 */ 649 public DSTModifyResponse modify(java.util.List items) 650 throws DSTException, InteractionRedirectException { 651 652 DSTUtils.debug.message("DSTClient:modify:init:"); 653 if(items == null) { 654 DSTUtils.debug.message("DSTClient:modify:null values"); 655 throw new DSTException(DSTUtils.bundle.getString("nullInputParams")); 656 } 657 658 DSTModify modify = null; 659 660 if(isEncryptedResourceID) { 661 modify = new DSTModify(encryptedResourceID, items, null); 662 } else { 663 modify = new DSTModify(resourceID, items, null); 664 } 665 666 List request = new ArrayList(); 667 request.add(DSTUtils.parseXML(modify.toString(true, true))); 668 669 List response = sendMessage(request); 670 if(response == null || response.size() == 0) { 671 DSTUtils.debug.message("DSTClient:modify: response is null"); 672 return null; 673 } 674 675 return new DSTModifyResponse((Element)response.get(0)); 676 677 } 678 679 /** 680 * Gets modify response for the specified modify. 681 * @param modify <code>DSTModify</code> object. 682 * @return <code>DSTModifyResponse</code> object. 683 * @exception DSTException if error occurs when trying to modify data 684 * @exception InteractionRedirectException if user agent is redirected to 685 * Web Service Provider (<code>WSP</code>) for resource owner 686 * interactions 687 */ 688 public DSTModifyResponse modify(DSTModify modify) 689 throws DSTException, InteractionRedirectException { 690 691 DSTUtils.debug.message("DSTClient:modify:init"); 692 if(modify == null) { 693 DSTUtils.debug.message("DSTClient:modify:null values"); 694 throw new DSTException(DSTUtils.bundle.getString("nullInputParams")); 695 } 696 697 List request = new ArrayList(); 698 request.add(DSTUtils.parseXML(modify.toString(true, true))); 699 700 List response = sendMessage(request); 701 return new DSTModifyResponse((Element)response.get(0)); 702 } 703 704 /** 705 * Gets query responses for a list of <code>DST</code> queries 706 * @param queries list of <code>DSTQuery</code> objects 707 * @return List of <code>DSTQueryResponse</code> objects, corresponding 708 * to each <code>DSTQuery</code> object. 709 * @exception DSTException if error occurs when trying to get data 710 * @exception InteractionRedirectException if interaction is required. 711 */ 712 public java.util.List getQueryResponse(java.util.List queries) 713 throws DSTException, InteractionRedirectException 714 { 715 DSTUtils.debug.message("DSTClient.getQueryResponse:Init"); 716 if(queries == null || queries.size() == 0) { 717 DSTUtils.debug.error("DSTClient.getQueryResponse:null values"); 718 throw new DSTException(DSTUtils.bundle.getString("nullInputParams")); 719 } 720 Iterator iter = queries.iterator(); 721 List requests = new ArrayList(); 722 while(iter.hasNext()) { 723 DSTQuery query = (DSTQuery)iter.next(); 724 requests.add(DSTUtils.parseXML(query.toString(true, true))); 725 } 726 List responses = sendMessage(requests); 727 if(responses == null || responses.size() == 0) { 728 DSTUtils.debug.error("DSTClient.getQueryResponse:null responses"); 729 throw new DSTException(DSTUtils.bundle.getString("nullResponse")); 730 } 731 List queryResponses = new ArrayList(); 732 Iterator iter1 = responses.iterator(); 733 while(iter1.hasNext()) { 734 queryResponses.add(new DSTQueryResponse((Element)iter1.next())); 735 } 736 return queryResponses; 737 } 738 739 /** 740 * Performs a list of modifications specified by a list of 741 * <code>DSTModify</code> objects (possible on different resource ID). 742 * 743 * @param modifies list of <code>DSTModify</code> objects specifying 744 * resource and modifications to be made. 745 * @return List of <code>DSTModifyResponse</code> object corresponding 746 * to each <code>DSTModify</code>. 747 * @exception DSTException if error occurs when trying to modify data 748 * @exception InteractionRedirectException if interaction is required. 749 */ 750 public java.util.List getModifyResponse(java.util.List modifies) 751 throws DSTException , InteractionRedirectException 752 { 753 DSTUtils.debug.message("DSTClient.getModifyResponse:Init"); 754 if(modifies == null || modifies.size() == 0) { 755 DSTUtils.debug.error("DSTClient.getModifyResponse:null values"); 756 throw new DSTException(DSTUtils.bundle.getString("nullInputParams")); 757 } 758 Iterator iter = modifies.iterator(); 759 List requests = new ArrayList(); 760 while(iter.hasNext()) { 761 DSTModify modify = (DSTModify)iter.next(); 762 requests.add(DSTUtils.parseXML(modify.toString(true, true))); 763 } 764 List responses = sendMessage(requests); 765 if(responses == null || responses.size() == 0) { 766 DSTUtils.debug.error("DSTClient.getModifyResponse:null responses"); 767 throw new DSTException(DSTUtils.bundle.getString("nullResponse")); 768 } 769 List modifyResponses = new ArrayList(); 770 Iterator iter1 = responses.iterator(); 771 while(iter1.hasNext()) { 772 modifyResponses.add(new DSTModifyResponse((Element)iter1.next())); 773 } 774 return modifyResponses; 775 776 } 777 778 /** 779 * Sends the SOAP Message to the data service. 780 * @param List of Request Objects. 781 * @return List of Response Objects. 782 * @exception DSTException for failure. 783 */ 784 private List sendMessage(List requestObjects) 785 throws DSTException, InteractionRedirectException { 786 787 DSTUtils.debug.message("DSTClient:sendMessage:Init"); 788 if(requestObjects == null || requestObjects.size() == 0) { 789 DSTUtils.debug.message("DSTClient:sendMessage: requestobj are null"); 790 throw new DSTException(DSTUtils.bundle.getString("nullInputParams")); 791 } 792 793 try { 794 Message msg = null; 795 796 ProviderHeader provH = null; 797 if(providerID != null) { 798 provH = new ProviderHeader(providerID); 799 } 800 801 if(securityProfile == Message.X509_TOKEN) { 802 if(token == null) { 803 throw new DSTException( 804 DSTUtils.bundle.getString("nullToken")); 805 } 806 DSTUtils.debug.message("DSTClient:sendMessage:using x509"); 807 msg = new Message(provH, token); 808 809 } else if(securityProfile == Message.SAML_TOKEN) { 810 DSTUtils.debug.message("DSTClient:sendMessage:using SAML"); 811 msg = new Message(provH, assertion); 812 813 } else if(securityProfile == Message.BEARER_TOKEN) { 814 DSTUtils.debug.message("DSTClient:sendMessage:using Bearer"); 815 msg = new Message(provH, assertion); 816 817 } else if(securityProfile == Message.ANONYMOUS) { 818 DSTUtils.debug.message("DSTClient:sendMessage:using Anonymous"); 819 msg = new Message(provH); 820 821 } else { 822 throw new DSTException( 823 DSTUtils.bundle.getString("invalidSecurityProfile")); 824 } 825 826 msg.setSOAPBodies(requestObjects); 827 msg.setWSFVersion(wsfVersion); 828 829 if(clientAuthEnabled) { 830 msg.setClientAuthentication(clientAuthEnabled); 831 } 832 833 if(DSTUtils.debug.messageEnabled()) { 834 DSTUtils.debug.message("DSTClient:sendMessage: request:" 835 + msg.toString()); 836 } 837 838 Message response = null; 839 840 if(httpRequest != null) { 841 response = handleInteraction(msg); 842 } else { 843 response = Client.sendRequest( 844 msg, soapURI, certAlias, soapAction); 845 } 846 847 if(DSTUtils.debug.messageEnabled()) { 848 DSTUtils.debug.message("DSTClient:sendMessage:response = " + 849 response.toString()); 850 } 851 852 serviceInstanceUpdateHeader = 853 response.getServiceInstanceUpdateHeader(); 854 855 return response.getBodies(); 856 857 } catch(SOAPBindingException sbe) { 858 DSTUtils.debug.error("DSTClient:sendMessage:soapbindexception",sbe); 859 throw new DSTException(sbe); 860 } catch(SOAPFaultException sfe) { 861 DSTUtils.debug.error("DSTClient:sendMessage:soapfault", sfe); 862 serviceInstanceUpdateHeader = 863 sfe.getSOAPFaultMessage().getServiceInstanceUpdateHeader(); 864 throw new DSTException(sfe); 865 } 866 } 867 868 /** 869 * Handles interaction request processing. 870 * When the interaction is required, it throws and InteractRedirect 871 * Exception, and redirect to the caller application(servlet). 872 */ 873 private Message handleInteraction(Message requestMsg) 874 throws DSTException, SOAPFaultException, 875 SOAPBindingException, InteractionRedirectException { 876 877 if(requestMsg == null || httpRequest == null || 878 httpResponse == null || soapURI == null) { 879 DSTUtils.debug.error("DSTClient:handeInteraction:null values"); 880 throw new DSTException( 881 DSTUtils.bundle.getString("nullInputParams")); 882 } 883 DSTUtils.debug.message("DSTClient:handleInteraction:init"); 884 String resend = httpRequest.getParameter( 885 InteractionManager.RESEND_MESSAGE); 886 String returnURL = httpRequest.getRequestURL().toString(); 887 Message response; 888 try { 889 InteractionManager manager = InteractionManager.getInstance(); 890 if(resend == null) { 891 //If the interaction is not required, this will send a 892 // original response. 893 response = manager.sendRequest(requestMsg, soapURI, certAlias, 894 soapAction, returnURL, httpRequest, httpResponse); 895 } else { 896 response = manager.resendRequest(returnURL, 897 httpRequest, httpResponse); 898 } 899 return response; 900 } catch (InteractionRedirectException ire) { 901 DSTUtils.debug.message("DSTClient:handleInteraction: Interaction" + 902 "Redirection happened."); 903 throw ire; 904 } catch (InteractionException ie) { 905 DSTUtils.debug.error("DSTClient:handleInteraction: Interaction" + 906 " Error occured.", ie); 907 throw new DSTException(ie); 908 } 909 } 910 911 /** 912 * Gets the <code>serviceInstanceUpdate</code> header from the SOAP 913 * response message. 914 * Applications can make use of this method to check if there is an 915 * alternate endpoint or credential available for the service requests. 916 * 917 * @return <code>ServiceInstanceUpdateHeader</code> from the response 918 * message. 919 */ 920 public ServiceInstanceUpdateHeader getServiceInstanceUpdateHeader() { 921 return serviceInstanceUpdateHeader; 922 } 923 924 /** 925 * Sets the web services version. 926 * 927 * @param wsfVersion the web services version that needs to be set. 928 */ 929 public void setWSFVersion(String wsfVersion) { 930 this.wsfVersion = wsfVersion; 931 } 932}
Copyright © 2010-2017, ForgeRock All Rights Reserved.