atg web services and integration framework guide - product version: 9 - oracle€¦ · atg web...
TRANSCRIPT
Version 9.4
Web Services and Integration Framework Guide
Oracle ATG
One Main Street
Cambridge, MA 02142
USA
ATG Web Services and Integration Framework Guide
Product version: 9.4
Release date: 10-31-11
Document identifier: WebServicesGuide1307251603
Copyright © 1997, 2011 Oracle and/or its affiliates. All rights reserved.
This software and related documentation are provided under a license agreement containing restrictions on use and disclosure and are
protected by intellectual property laws. Except as expressly permitted in your license agreement or allowed by law, you may not use, copy,
reproduce, translate, broadcast, modify, license, transmit, distribute, exhibit, perform, publish, or display any part, in any form, or by any
means. Reverse engineering, disassembly, or decompilation of this software, unless required by law for interoperability, is prohibited.
The information contained herein is subject to change without notice and is not warranted to be error-free. If you find any errors, please
report them to us in writing. If this software or related documentation is delivered to the U.S. Government or anyone licensing it on behalf of
the U.S. Government, the following notice is applicable:
U.S. GOVERNMENT RIGHTS
Programs, software, databases, and related documentation and technical data delivered to U.S. Government customers are "commercial
computer software" or "commercial technical data" pursuant to the applicable Federal Acquisition Regulation and agency-specific
supplemental regulations. As such, the use, duplication, disclosure, modification, and adaptation shall be subject to the restrictions and
license terms set forth in the applicable Government contract, and, to the extent applicable by the terms of the Government contract, the
additional rights set forth in FAR 52.227-19, Commercial Computer Software License (December 2007). Oracle America, Inc., 500 Oracle
Parkway, Redwood City, CA 94065.
This software or hardware is developed for general use in a variety of information management applications. It is not developed or intended
for use in any inherently dangerous applications, including applications that may create a risk of personal injury. If you use this software or
hardware in dangerous applications, then you shall be responsible to take all appropriate fail-safe, backup, redundancy, and other measures
to ensure its safe use. Oracle Corporation and its affiliates disclaim any liability for any damages caused by use of this software or hardware in
dangerous applications.
Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners.
Intel and Intel Xeon are trademarks or registered trademarks of Intel Corporation. All SPARC trademarks are used under license and are
trademarks or registered trademarks of SPARC International, Inc. AMD, Opteron, the AMD logo, and the AMD Opteron logo are trademarks or
registered trademarks of Advanced Micro Devices. UNIX is a registered trademark licensed through X/Open Company, Ltd.
This software or hardware and documentation may provide access to or information on content, products, and services from third parties.
Oracle Corporation and its affiliates are not responsible for and expressly disclaim all warranties of any kind with respect to third-party
content, products, and services. Oracle Corporation and its affiliates will not be responsible for any loss, costs, or damages incurred due to
your access to or use of third-party content, products, or services.
For information about Oracle's commitment to accessibility, visit the Oracle Accessibility Program website at http://www.oracle.com/us/
corporate/accessibility/index.html.
Oracle customers have access to electronic support through My Oracle Support. For information, visit http://www.oracle.com/support/
contact.html or visit http://www.oracle.com/accessibility/support.html if you are hearing impaired.
ATG Web Services and Integration Framework Guide iii
Table of Contents
I. Creating and Using Web Services in the ATG Platform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1. Creating Custom Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Overview of ATG Web Services Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
JAX-RPC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Automatic Generation of Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Session and Security Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Web Service Creation Wizard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Using the Wizard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Naming Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Anatomy of a Web Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Service Endpoint Interface and Implementation Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
WSDL Document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
web.xml File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
JAX-RPC Deployment Descriptor and Mapping Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Runtime Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
JSR 109 Compliant EAR File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Web Service Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Security Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Creating and Editing Security Configurations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Deploying Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Managing Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Registering Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2. Creating JMS Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Using the JMS Message Web Service Wizard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Structure of a JMS Web Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Patch Bay Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3. Creating Repository Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Using the Repository Web Service Wizard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Repository Web Service Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Modifying Repository Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
RepositoryService Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4. Repository to XML Data Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Mapping Files and XML Schemas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Mapping Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Managing Mapping Files for Repository Item Descriptors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
XML Schemas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Managing Schemas and Mapping Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
PropertyElementNameSeparator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Item References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Repository Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Getting Repository Items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Adding Repository Items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Updating Repository Items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Removing Repository Items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
5. Accessing ATG Web Services from Java Clients . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
About ATG Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Sharing Sessions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
RepositoryItems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
iv ATG Web Services and Integration Framework Guide
Before You Begin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Writing a CookieContainer Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Calling ATG Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Creating a Call Using a Client Stub (Static) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Creating a Call Using the Dynamic Invocation Interface (Dynamic) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Creating a Serializer and Deserializer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Creating a Mapping File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Generating an XML Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
6. Accessing ATG Web Services from .NET Clients . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
About Web Services in the ATG Platform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Session Sharing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Client Stubs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Web Services that Access RepositoryItems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Before You Begin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Installing ATGWS.dll . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Calling ATG Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Accessing an ATG Web Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Accessing a Custom ATG Web Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Sample Web Service Calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
Using the Atg.DotNet.WebService API to Serialize and Deserialize RepositoryItems . . . . . . . . . . . . . . . . . 58
RepositoryItem Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Property Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
RepositoryItemRef Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Complex Type Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
NoSuchPropertyException Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
RepositoryItemSerializer Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
RepositoryItemSerializationException Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
II. Integration Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
7. Integration Repository . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Integration Approaches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Remote Only . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Remote then Local . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Local then Remote . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Local Only . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Setting Up an Integration Repository . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Defining an Integration Repository . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Integration Repository APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
IntegrationRepository . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
IntegrationRepositoryItemDescriptor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
IntegrationRepositoryItem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
ChangedPropertyBean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
atg.repository.databinding.MappingRepositoryItem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
IntegrationRepositoryView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Command Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
executeQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
getItem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
updateItem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
addItem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
removeItem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
ATG Web Services and Integration Framework Guide v
Persistent Caching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Cleaning up the Persistent Cache . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Configuration Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
Configuring the Remote-Only Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
Configuring the Remote-then-Local Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Configuring the Local-then-Remote Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Integration Repository Definition File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
integration-repository-template tag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
header tag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
item-descriptor tag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
item-descriptor Child Tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
integration-repository Document Type Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
8. Remote Procedure Calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
RPC API Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Command Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
CommandHandler Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
CommandResult Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Implementing the RPC API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Exception Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Executing Commands in Pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
III. ATG Platform REST Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
9. Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Starting the ATG Server with the REST Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Setting the Default ACL for REST Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Configuring the Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Creating Simple Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
10. Client Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Java Client Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Creating Requests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Creating a RestSession Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Logging in and Logging Out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Accessing Data from the Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
Creating a Raw REST Request . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Handling Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
ActionScript Client Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
atg.rest.client.RestComponentHelper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
atg.rest.client.RestRepositoryHelper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
11. Working with Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
A Note about Output Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
A Note about Nucleus Component Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Getting Component Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Getting and Setting Property Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
12. Calling Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Passing Parameters to Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Calling Handler Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
Passing Parameters to Form Handlers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Calling Methods with ActionScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
13. Working with Repository Items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
About Output Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
About Repository Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
Getting Repository Items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
Repository IDs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
Adding Repository Items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
vi ATG Web Services and Integration Framework Guide
Deleting Repository Items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
Getting Repository Item Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
Setting Repository Item Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
Performing Queries for Repository Items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
14. Input and Output Formats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Parsing Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
JSON Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
XML Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
Formatting Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
Formatting Input with ActionScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
15. Property Filtering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
Property Aliasing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
16. Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
Global Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
Component Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
Property and Method Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
Securing Groups of Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
17. Control Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
18. HTTP Status Codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
Error Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
Part I. Creating and Using Web
Services in the ATG PlatformA common requirement for enterprise applications is the ability to share data and business logic with other applications. For
example, suppose you have an employee portal built with the ATG platform, and also a payroll system based on some other
software package. When a new employee starts, or an existing employee changes his or her marital status, you need to create
or modify the employee’s profile in both systems. Ideally, you’d like the employee to be able to make the changes in one
application and have those changes automatically propagate to the other application.
One way to address this issue is through Web services, a widely supported standard for packaging remote procedure calls
in an XML-based structure. In the example above, you could create a Web service that automatically updates an employee’s
profile in the employee portal when the information in the payroll system is modified.
The Dynamo Application Framework includes tools that allow you to create custom Web services that call methods on
Nucleus components. These custom Web services can expose methods on existing ATG Nucleus components, or on Nucleus
components you write yourself. You can call these Web services from an external application client, such as the payroll
system mentioned above.
The ATG platform packages Web services as: J2EE applications, in accordance with the JAX-RPC (JSR 101) and Implementing
Enterprise Web Services (JSR 109) specifications. Note that this manual assumes that you’re familiar with these specifications,
and with Web services in general. For more information about these specifications, see the Java Community Process web site
at:
http://www.jcp.org
The chapters in this section discuss how to create Web services in the ATG platform, and how to write Java and .NET clients
that call these services:
Creating Custom Web Services (page 5)
Creating JMS Web Services (page 19)
Creating Repository Web Services (page 23)
Repository to XML Data Binding (page 27)
Accessing ATG Web Services from Java Clients (page 41)
Accessing ATG Web Services from .NET Clients (page 53)
ATG Web Services
In addition to any Web services you create, the ATG platform includes a number of prepackaged Web services that you can
call from Java and .NET clients. These services are packaged in three separate application modules. You can include any of
these services in an assembled EAR file by including the module that contains the desired services. For example, to include
the prepackaged Commerce Web services, specify the DCS.WebServices module when you assemble your application.
The following table summarizes these Web services:
Application Module Web Application Web Services
DAS.WebServices
For more information about
these Web services, see the
ATG Repository Guide.
Generic Repository
Services
- getRepositoryItem
- performRQLQuery
- performRQLCountQuery
User Session - loginUser
- logoutUser
- getProfileId
- setLocale
- setContactInfo
- setPassword
- getProfile
- createUser
- updateUser
- getPasswordHashKey
- getPasswordHashAlgorithm
- canClientEncryptPasswords
- executeRepositoryTargeter
DPS.WebServices
For more information about
these Web services, see
the ATG Personalization
Programming Guide
Messaging - sendPageVisit
- sendClickThrough
DCS.WebServices
For more information about
these Web services, see ATG
Commerce Programming
Guide.
Order - createOrderFromXML
- submitOrderWithReprice
- cancelOrder
- getOrderStatus
- getOrderAsXML
- getOrdersAsXML
- getOrderStatus
- getCurrentOrderId
- addItemToOrder
- addItemToShippingGroup
- createOrder
- createOrderForUser
- removeItemFromOrder
- setItemQuantity
- addCreditCardToOrder
- addShippingAddressOrder
- removePaymentGroupFromOrder
- removeCreditCardFromOrder
- removeShippingGroupFromOrder
- moveItemBetweenShippingGroups
- removeItemQuantityFromShippingGroup
- setOrderAmountToPaymenGroup
- getDefaultPaymentGroupId
- getDefaultShippingGroupId
Application Module Web Application Web Services
Pricing - calculateOrderPrice
- calculateOrderPriceSummary
- calculateItemPriceSummary
Promotions - grantPromotion
- revokePromotion
- claimCoupon
- getPromotionsAsXML
Inventory - getInventory
- getInventoryStatus
- setStockLevel
- setStockLevels
Catalog - getProductXMLById
- getProductXMLByDescription
- getProductXMLByRQL
- getProductSkusXML
- catalogItemViewed
Profile - setDefaultShippingAddress
- setDefaultBillingAddress
- setDefaultCreditCard
- getDefaultShippingAddress
- getDefaultBillingAddress
- getDefaultCreditCard
1 Creating Custom Web Services 5
1 Creating Custom Web Services
The ATG platform provides infrastructure and tools that enable you to expose a wide range of ATG functionality
as Web services. There are three kinds of Web services you can create that expose ATG functionality:
• Web services that invoke methods on Nucleus components.
• Web services that send JMS messages through Patch Bay.
• Web services that perform operations on repository items.
This chapter describes the infrastructure for creating these services. It focuses on Web services that invoke
Nucleus methods, but most of what is described here applies to all three types of services. For information
specific to Web services that send JMS messages, see the Creating JMS Web Services (page 19) chapter.
For information specific to Web services that perform repository operations, see the Creating Repository Web
Services (page 23) chapter.
This chapter includes the following sections:
Overview of ATG Web Services Support (page 5)
Web Service Creation Wizard (page 7)
Anatomy of a Web Service (page 9)
Web Service Security (page 13)
Deploying Web Services (page 15)
Managing Web Services (page 16)
Overview of ATG Web Services Support
This section describes key aspects of the ATG Web services support:
• JAX-RPC
• Automatic generation of Web services
• Session and security support
• Limitations
6 1 Creating Custom Web Services
JAX-RPC
The Web services support in the ATG platform is based on JAX-RPC (Java API for XML-based RPC). The JAX-
RPC specification defines a standard way for incoming XML-based SOAP messages to be converted to Java-
based RPC calls. The ATG platform uses Sun’s reference implementation of JAX-RPC. Parts of this reference
implementation are used to generate Web services, and other parts of it handle the processing of SOAP
messages when a Web service is called.
Automatic Generation of Web Services
Creating a Web service by hand can be a laborious process, due to the large number of Java and XML files you
must create and package. The ATG platform automates this process through the Web Service Creation Wizard
in the Dynamo Administration UI. You select the type of service you want to generate, and the wizard takes you
through a series of screens where you specify the necessary information. You then click a button, and the wizard
automatically generates the necessary classes, WSDL documents, and deployment descriptors, and packages
them in EAR and WAR files.
Session and Security Support
When you create a Web service, you specify whether it should be executed within the context of an HTTP
session. Associating Web services with a session enables an application to maintain state across Web service
calls and to use login information for security purposes.
To enable multiple Web services to execute within the same session, a client application must pass a session
cookie between calls. Some Web services frameworks, such as Microsoft’s .NET, provide support for passing
session cookies. Java clients typically require applications to manage session cookies themselves.
For more information about using sessions with Java clients, see the Accessing ATG Web Services from Java
Clients (page 41) chapter. For more information about using sessions with .NET clients, see the Accessing ATG
Web Services from .NET Clients (page 53) chapter.
Limitations
You can create Web services from most Nucleus methods, both from components ATG provides and
components that you write. There are, however, some methods that cannot be exposed as valid Web services.
The Web Service Creation Wizard will not create Web services from these methods. In particular, it enforces the
following restrictions by preventing you from selecting these methods:
• You cannot create a Web service from any method that has a parameter or return type that is an abstract data
type (such as a Map, Collection, Interface, abstract class, or an object with abstract data type properties).
• You cannot create a Web service from any method that has a parameter or return type that is a wrapper class
for a primitive data type. The prohibited classes are Byte, Boolean, Character, Integer, Short, Long,
Float, and Double. Note, however, that methods that use actual primitives are valid. If there is a method that
you want to expose that has one of these wrapper classes as a parameter or return type, you can either rewrite
the method to use a primitive instead (if the method’s class is your own custom code), or else subclass the
method’s class (if it is a class provided by ATG) and overload the method with a version that uses primitives.
In addition, you cannot create a Web service from a method that has the same name and signature as any of
the methods of atg.webservice.ManagedComponentProperties or java.lang.Object. Attempting to
1 Creating Custom Web Services 7
do so results in a naming conflict, because the service implementation class of each Web service subclasses
atg.webservice.ManagedComponentProperties, which subclasses java.lang.Object. Note that the
wizard does not prevent you from selecting these methods, but when you try to generate a Web service, an
exception is thrown and the service generation fails.
Web Service Creation Wizard
The process of creating Web services is automated by the Web Service Creation Wizard in the Dynamo
Administration UI. This wizard guides you through the steps of selecting a Nucleus component and method,
specifying input parameters and other settings; it then automatically creates the Web service by performing the
following steps:
• Create the service endpoint interface that specifies the method to be exposed.
• Create the service endpoint class that implements the service endpoint interface and is responsible for
handing incoming SOAP requests.
• Create the WSDL document that describes the resources required by the service endpoint class, as well as its
inputs and outputs.
• Create the web.xml file for the Web application that the service is a part of.
• Create the JAX-RPC deployment descriptor (webservices.xml) and mapping file.
• Build the runtime classes.
• Package these elements in a JSR 109 compliant EAR file.
These steps are described in more detail in the Anatomy of a Web Service (page 9) section.
The wizard uses the component /atg/webservice/WebServiceGenerator to perform the actual work of
generating the service. This component, which is of class atg.webservice.WebServiceGeneratorImpl,
performs all of the operations listed above, either through its own methods or through other components it
refers to.
Using the Wizard
The top-level page of the Dynamo Administration UI includes a Web Service Administration link. This link takes
you to the Web Service Administration page, which has three links for working with Web services:
• Web Service Registry – Takes you to a page for viewing and managing currently loaded Web services. The
Web services registry is discussed in the section Managing Web Services (page 16).
• Web Service Security Manager – Enables you to create and edit Web service security configurations.
These security configurations can be used to define which users can access specific Web services. When you
create a Web service, you have the option of associating a security configuration with the service. Security
configurations are discussed in the section Web Service Security (page 13).
• Web Service Creation Wizard – Takes you to a page with links for creating each of the three kinds of Web
services (Component Method Web Service, JMS Message Web Service, Repository Web Service).
8 1 Creating Custom Web Services
To create a Web service that invokes a method on a Nucleus component, starting from the Web Service
Administration page:
1. Click the Web Service Creation Wizard link. This takes you to a page titled Select Type, where you can select
the type of Web service to create.
2. Click the Component Method Web Service link. This takes you to the Select Nucleus Component page.
3. On the Select Nucleus Component page, specify the pathname of the Nucleus component you want to create
the Web service from. You can either enter the pathname directly in the field at the top of the page and then
click the Next button, or you can use the component browser below it to navigate to the component and
select it.
4. On the Select A Method page, select the method you want to expose as a Web service.
5. If the method requires any input parameters, the Set Parameter Names page provides you with fields for
specifying the names of these parameters. The names you specify are used for the parameters of the Web
service call, and can be anything you like.
When the Web service is called, the service passes the values of these parameters to the parameters of the
exposed Nucleus method. There is thus a one-to-one correspondence between the parameters of the Web
service call and the parameters of the underlying Nucleus methods.
6. The next two pages are titled EAR Name & Servlet Settings and Enterprise and Web Application Settings.
When the wizard creates a Web service, it packages it in a WAR file, which is in turn packaged in an EAR file.
It is possible to have any number of services in a single Web application (WAR file), and any number of Web
applications in a single Enterprise application (EAR file). This flexibility gives you a good deal of control over
how you deploy your Web services. For each new Web service, the wizard can do any of the following:
• Create a new EAR file for the service, and put it in a WAR file within the EAR file.
• Use an existing EAR file, and put the service in a new WAR file within it.
• Put the service in an existing WAR file within an existing EAR file.
To add a Web service to an existing EAR file, you specify that file as the EAR file name on the EAR Name &
Servlet Settings page. The Web Application Settings page then gives you the choice of creating a new Web
application for the service, or adding the service to an existing Web application.
The wizard also gives you the option of specifying the host name and port number for a Web service, or of
leaving these fields blank. If you leave the fields blank, the values are dynamically assigned at runtime from
the URL used for the WSDL file request.
7. The Session & Security Options page allows you to specify whether the Web service should be executed
within the context of an HTTP session. The wizard gives you these options:
• Neither provide a session nor security constraints.
• Provide a session, but no security constraints.
• Provide both a session and security constraints.
If you want to call the Web service from a client that uses sessions or session sharing, you must choose
one of the last two options. If you choose the last option, the wizard then prompts you to select a security
configuration. See Web Service Security (page 13) for information about security configurations for Web
services.
8. On the Create EAR File page, click the Create EAR File button to create the Web service.
1 Creating Custom Web Services 9
If there is already an EAR file with the specified name, the wizard first appends .old to the name of the
existing file so that new file does not overwrite it.
Once you have created an EAR file, you must deploy it in order to run the Web services in it. See the Deploying
Web Services (page 15) section for more information.
Naming Restrictions
Most of the class names and filenames for Web services are generated automatically by the wizard. As a result,
certain circumstances can result in naming conflicts. For example, if you create a Web service from a Nucleus
method, you cannot then create a second Web service from another method with the same name (such as
an overloaded method) and put it in the same WAR file, even if the two methods have different signatures or
capitalization. If you attempt to do this, the second Web service will simply overwrite the first.
To prevent the second service from overwriting the first, put the second service in a different WAR file. In
addition, be sure to give the second WAR file a different context root from the first WAR file. (The default value
for the context root in the wizard is based on the method name, so you’ll need to change the value when you
run the wizard.) It will then be possible to differentiate calls to the two services based on their context roots.
Anatomy of a Web Service
As mentioned above, the Web Service Creation Wizard automatically performs a number of tasks, greatly
simplifying the creation of Web services from Nucleus components. The wizard enables you to simply create
Web services and begin using them, without needing to understand all of their underpinnings. However, in
some cases you may need to troubleshoot or make changes to your Web services, so it is helpful to have some
familiarity with their form and packaging. This section discusses the various pieces that make up a Web service,
including:
• service endpoint interface and implementation class
• WSDL document
• web.xml file
• JAX-RPC deployment descriptor (webservices.xml) and mapping file
• runtime classes
• JSR 109 compliant EAR file
Note that the business logic of the Web service is actually contained in the method of the Nucleus component
that is being exposed. The Web service handles only the RPC infrastructure, and passes the actual processing to
the Nucleus component.
Service Endpoint Interface and Implementation Class
The service endpoint interface (SEI) is a Java interface class that defines the methods to be exposed as a
Web service. This interface must extend the java.rmi.Remote interface and each method must throw
10 1 Creating Custom Web Services
java.rmi.RemoteException. The SEI for any Web service generated by the ATG platform has a single method,
corresponding to the Nucleus method being exposed.
The service implementation class (also referred to as the service bean) implements the service endpoint
interface and handles the actual servicing of incoming SOAP requests. In addition, service implementation
classes generated by the ATG platform implement the interface javax.xml.rpc.server.ServiceLifecyle,
and extend the atg.webservice.ManagedComponentProperties class, which registers services with the
ATG platform Web Service Registry. The Web Service Registry is discussed in the Managing Web Services (page
16) section.
The service endpoint interface and implementation class are generated by the /atg/webservice/
WebServiceGenerator component. The names for these classes are based on the name of the Nucleus
method being exposed. For instance, if the Nucleus method is getOrderStatus, the service endpoint interface
is named GetOrderStatusSEI, and the implementation class is named GetOrderStatusSEIImpl.
WSDL Document
Web Services Description Language (WSDL) is an XML language for describing Web services in a platform-
independent way. A WSDL document describes a Web service’s methods by specifying the locations of the
resources they use and defining the methods’ inputs and outputs. (A WSDL document for a Web service
generated by the ATG platform always describes one method, because each Web service can expose only one
Nucleus method.)
There must be a separate WSDL document for each Web service. The WSDL document is generated by the /
atg/webservice/WSDLGenerator component, which is of class atg.webservice.WSDLGeneratorImpl.
This document is used for two key purposes:
• It is used by the JAX-RPC API to generate runtime classes.
• At runtime, it is used by Web service clients to look up the semantics of the SOAP messages to send to invoke
the service.
When the Web service’s input and output values are primitive types, they are defined in the primary WSDL
document. For example:
<message name="getOrderStatusInput"> <part name="in0" type="xsd:string"></message>
Each non-primitive input or output requires its own WSDL document that is imported by the primary WSDL
document. Import statements similar to the following are included in the primary WSDL document when the
Web service is created using the Dynamo Administration UI:
<import location="atg.commerce.order.status.wsdl" namespace="http://www.atg.com/atg.commerce.order.status"/>
The location specified is relative to the primary WSDL document. Some Web service clients
are able to interpret relative locations, but others require fully qualified URLs. To work with these
clients, when the ATG platform receives a request for a WSDL document, it uses the servlet class
atg.webservice.WSDLFinderServlet and the filter class atg.webservice.WSDLImportFilter to
translate the location value into a fully qualified URL:
1 Creating Custom Web Services 11
1. At runtime, JAXRPCServlet updates the SOAP address in the WSDL document to include the domain host
name and port number.
2. When WSDLFinderServlet detects a WSDL request, WSDLImportFilter appends the domain name
and port number (from the SOAP address provided by JAXRPCServlet) and the context path (by calling
request.getContextPath() on the Dynamo request) to the location value in the import statement. The
resulting import statement looks similar to this:
<import location=
"http://myhost:7881/catalog/atg.commerce.order.status.wsdl"
namespace="http://www.atg.com/atg.commerce.order.status"/>
The WSDLFinderServlet and WSDLImportFilter classes are declared in the web.xml file for the Web
application that the Web service is a part of, as discussed in the next section. For more information about
request handling, see the ATG Programming Guide.
web.xml File
The web.xml file is the standard deployment descriptor for the Web application that the Web service is a part of.
It declares the filters and servlets used by the service.
On the ATG platform, the servlet that listens for the SOAP request is
com.sun.xml.rpc.server.http.JAXRPCServlet. This servlet is part of the JAX-RPC reference
implementation, and is responsible for receiving the incoming SOAP request and determining how to dispatch
the call. For example, if you create a Web service called getOrderStatus, the entry for it in the web.xml file
looks something like this:
<servlet> <servlet-name>getOrderStatus</servlet-name> <display-name>getOrderStatus</display-name> <servlet-class>com.sun.xml.rpc.server.http.JAXRPCServlet</servlet-class> <init-param> <param-name>configuration.file</param-name> <param-value>WEB-INF/wsconfig/getOrderStatus_Config.properties</param-value> </init-param></servlet>...<servlet-mapping> <servlet-name>getOrderStatus</servlet-name> <url-pattern>/getOrderStatus/*</url-pattern></servlet-mapping>
When a call to the getOrderStatus Web service is sent to the ATG platform, the JAXRPCServlet receives the
request and dispatches it based on the information in the file that the configuration.file parameter points
to. This configuration file is included in the WAR file, and looks similar to this:
port0.wsdl.serviceName=GetOrderStatusSEIServiceport0.tie=webservices.GetOrderStatusSEI_Tiewsdl.transform=trueport0.name=getOrderStatusportcount=1wsdl.location=WEB-INF/getOrderStatus.wsdlport0.servant=webservices.GetOrderStatusSEIImplport0.wsdl.targetNamespace=http\://www.atg.com/webservices
12 1 Creating Custom Web Services
port0.wsdl.portName=GetOrderStatusSEIPort
Note that the port0.servant property is set to the name of the service implementation class. This property
designates the class that JAXRPCServlet dispatches the SOAP request to.
Handling Imported WSDL Documents
As discussed in the WSDL Document section, there are two resources that assist in handling WSDL requests.
These resources are declared in the web.xml file:
• WSDLImportFilter, which is a filter of class atg.webservice.WSDLImportFilter, is mapped to a parent
directory that has subdirectories holding WSDL documents.
• WSDLFinder, which is a servlet of class atg.webservice.WSDLFinderServlet, should be defined and
mapped to each path that will lead to a WSDL document.
For example:
<filter> <filter-name>WSDLImportFilter</filter-name> <filter-class>atg.webservice.WSDLImportFilter</filter-class></filter>...<filter-mapping> <filter-name>WSDLImportFilter</filter-name> <url-pattern>/getOrderStatus/*</url-pattern></filter-mapping>...<servlet> <servlet-name>WSDLFinder</servlet-name> <display-name>WSDLFinder</display-name> <description>Used to lookup imported wsdl files.</description> <servlet-class>atg.webservice.WSDLFinderServlet</servlet-class></servlet>...<servlet-mapping> <servlet-name>WSDLFinder</servlet-name> <url-pattern>atg.commerce.order.status.wsdl</url-pattern></servlet-mapping><servlet-mapping> <servlet-name>WSDLFinder</servlet-name> <url-pattern>atg.security.wsdl</url-pattern></servlet-mapping><servlet-mapping> <servlet-name>WSDLFinder</servlet-name> <url-pattern>atg.commerce.wsdl</url-pattern></servlet-mapping>
Web Service Registrar
To register Web services with the Web Services Registry, the web.xml file declares the WebServiceRegistrar
servlet, and sets it to load on startup:
<servlet> <servlet-name>WebServiceRegistrar</servlet-name> <display-name>WebServiceRegistrar</display-name> <description>ATG WebServiceRegistrar for registering servlet
1 Creating Custom Web Services 13
web-services.</description> <servlet-class>atg.webservice.WebServiceRegistrar</servlet-class> <load-on-startup>1</load-on-startup></servlet>
For more information about the Web Services Registry, see Managing Web Services (page 16).
Other Elements of web.xml
The web.xml file may declare certain additional elements:
• the servlet atg.nucleus.servlet.NucleusServlet, which runs Nucleus as a servlet within a Web
application
• the filter atg.filter.dspjsp.PageFilter, which invokes the DAF request-handling pipeline
• the context parameter atg.session.parentContextName; its value is set to /dyn, which enables the Web
services to share information with the atg_bootstrap.war application
JAX-RPC Deployment Descriptor and Mapping Files
The JAX-RPC deployment descriptor, webservices.xml, provides metadata (such as names and descriptions of
the SEIs, service beans, and WSDL documents) about all of the Web services in a given Web application.
The mapping file defines the association between a WSDL file and an SEI and implementation class, by mapping
namespaces to Java packages. This mapping is used when serializing and deserializing XML files. There is a
separate JAX-RPC mapping file for each Web service, and the name of each file reflects the method the service
is based on. For example, if the method is getOrderStatus, the mapping file for the Web services is named
getOrderStatusMapping.xml.
Runtime Classes
The runtime classes are generated using the Sun JAX-RPC reference implementation. These classes include:
• the tie class that JAXRPCServlet invokes the method on, and which in turn invokes the method on the
service implementation class
• classes for handling serializing and deserializing SOAP requests and responses
JSR 109 Compliant EAR File
The JSR 109 Java specification includes information about how a Web service should be packaged within an EAR
file. The wizard combines all the generated files (class files, web.xml, WSDL document, webservices.xml, and
JAX-RPC mapping file) into a WAR file, which is then added to a JSR 109 compliant EAR file.
Web Service Security
When you create a Web service, you have the option of applying security constraints so that only approved
clients (those with administrator privileges, for example) can execute it. You specify the security constraints
14 1 Creating Custom Web Services
using a security configuration, which is a repository item that stores information that controls access to
the Web service. You can create any number of different security configurations using the Web Services
Administration UI, and you can apply a security configuration to any number of Web services.
A security configuration has a corresponding security policy component, plus an optional ACL. A security
configuration is identified by its functional name, which is a property of the repository item that maps the
security configuration to a security component and ACL.
This section describes the main components involved in securing Web service methods, as well as how to create
security configurations through the Web Services Administration UI. For a broader discussion of the ATG security
API, see the Managing Access Control chapter in the ATG Programming Guide.
Security Components
There are two primary components involved in securing a Web service method:
• /atg/webservice/security/NucleusSecurityManager (an instance of
atg.webservice.NucleusSecurityManager) uses the security configuration associated with the Web
service to apply the corresponding security policy and ACL, to determine whether to grant or deny access.
• /atg/webservice/security/NucleusSecurityRepository (an instance of
atg.adapter.gsa.GSARepository) stores the Web service security configurations used by the
NucleusSecurityManager.
NucleusSecurityManager
At startup time, the NucleusSecurityManager retrieves the repository items from the
NucleusSecurityRepository (described below) and creates an internal mapping between each functional
name and the SecurityPolicy component and ACL associated with it.
When a client calls a Web service, the service invokes the hasAccess() method on the /atg/webservice/
security/NucleusSecurityManager component, passing it the functional name of the service’s security
configuration, the name of the Nucleus component and method exposed by the service, and a Map containing
the method’s parameters. The NucleusSecurityManager uses the functional name to find the associated
SecurityPolicy component and ACL, applies them to the call, and returns the result (true or false) to the
client. If true is returned, the Nucleus method exposed by the Web service is invoked; if false is returned,
access to the method is denied, and an exception of class atg.security.SecurityException is thrown.
If the NucleusSecurityManager is unable to apply the security configuration to a Web service call (for
example, if the SecurityPolicy is not valid), it determines whether to grant access based on the value of
its defaultGrantAccess property. The default value of this property is true (grant access). This setting
facilitates the development process, because it allows any Web service that does not have an associated security
configuration to be called by any client.
For deployment purposes, though, this behavior is undesirable, because of the security risks involved. Therefore,
when you enable liveconfig settings for the ATG platform, the defaultGrantAccess property is set
to false. Note, however, that this means that each of your Web services must have an associated security
configuration, because any call to a service without a security configuration will fail.
For information about enabling liveconfig settings, see the ATG Installation and Configuration Guide.
NucleusSecurityRepository
Web service security configurations are stored in the NucleusSecurityRepository. This repository includes
a single item descriptor called nucleusSecurity, which has properties called functionalName, policy, and
ACL. The NucleusSecurityManager parses the items in this repository at startup time.
1 Creating Custom Web Services 15
The Web Services Administration interface provides an easy way to add new security configurations to this
repository. See the next section for details.
Creating and Editing Security Configurations
The Web Services Administration page in the Dynamo Administration UI includes a Web Service Security
Manager link that takes you to a page that where you can view and edit the security configurations stored in
the NucleusSecurityRepository, or create new security configurations.
Follow these steps to create a new security configuration:
1. Click the Create New link.
2. On the Create Security Configuration page, enter a name for the security configuration in the Functional
Name field, and click Create New button.
3. On the Edit Web Service Security Configuration page, click the Add buttons to add users, roles, and
organizations to the security configuration. You can change the security policy (from the /atg/dynamo/
security/SecurityPolicy default) if necessary.
The new security configuration appears on the main Web Service Security Configurations page. If you need to
make changes to it, click the Edit link to open the Edit Web Service Security Configuration page. Note that you
cannot change the functional name.
Deploying Web Services
When you create a Web service, the wizard places the EAR file in the <ATG9dir>/home directory. The Web
service is not ready to run, however, because it does not include the necessary Nucleus classes.
In order to run the Web service, these additional steps are necessary:
1. Use the runAssembler command to assemble a Nucleus-based application, using the
-add-ear-file flag to incorporate the contents of the Web services EAR file.
2. Deploy the assembled EAR file on your application server, and start up the application.
For example, if your Web services EAR file is called WS.ear, you might use a command like this to assemble a
Nucleus-based application named MyApp.ear:
runAssembler -add-ear-file WS.ear MyApp.ear -m MyApp DSS
If you make any subsequent changes to the Web service, you must reassemble and redeploy the application for
the changes to take effect.
Note that in addition to any Web services you create, the ATG platform includes a number of prepackaged
Web services. These services are packaged in three separate application modules. You can include any of these
services in an assembled EAR file by including the module that contains the desired services. For example, to
include the prepackaged Commerce Web services, specify the DCS.WebServices module when you assemble
your application.
16 1 Creating Custom Web Services
For more information about the runAssembler command, see the ATG Programming Guide. For information
about deploying EAR files, see the documentation from your application server vendor.
Managing Web Services
The Dynamo Administration UI provides a facility for managing the Web services deployed on your server.
To access this facility, open the top-level page of the Dynamo Administration UI and click the Web Service
Administration link. On the Web Service Administration page, click the Web Service Registry link. This takes
you to the page for the /atg/webservice/WebServiceRegistry component, which stores information
about the available Web services.
For example, if the Web services included with ATG Commerce are running on your Dynamo server, the top of
the page will look similar to this:
The Service Info indicates that there are six Web applications running that include Web Services. You can get
more information about the services in a Web application by clicking the details link next to the application’s
name. For example, if you click on the link for the Pricing application, the Service Info looks like this:
1 Creating Custom Web Services 17
The lower table summarizes the status of the Web services in the Web application. The Name and URI
Pattern are the values of the display-name and url-pattern tags in the web.xml file, and the WSDL file
is the value of the wsdl.location property in the configuration file for the JAXRPCServlet. The Security
functional name is the name that the service implementation class passes to the hasAccess() method of the
NucleusSecurityManager to determine if the client has permission to call the Web service.
Some of the information shown in this table, such as the functional name, does not appear until the Web service
has been executed. If a service has been executed, the Instance Running and Registered value is true. You can
stop a running service by clicking the Off link in the Enabled column.
Registering Services
Web services generated by the Web Service Creation Wizard have the necessary code and configuration
information to register the Web service with the Web Service Registry.
To register the service, the service implementation class extends the class
atg.webservice.ManagedComponentProperties, which includes a register() method for registering
the service. In addition, the web.xml file for the Web application the service is part of declares the
WebServiceRegistrar servlet, as described in the Web Service Registrar (page 12) section.
2 Creating JMS Web Services 19
2 Creating JMS Web Services
In addition to Web services that call Nucleus methods, the ATG platform enables you to create Web services that
send JMS messages through Patch Bay. Many events in the ATG platform are triggered by JMS messages, so by
calling a Web service that sends a JMS message, a client can start execution of various services and processes. In
particular, scenario actions are triggered by JMS messages, so you can use Web service calls to invoke scenario
actions remotely. For example, suppose a new user registers in some application, which invokes a Web service
that sends the registration information to the ATG platform. The client application could then call a Web service
that sends a JMS message of type atg.dps.Register into Patch Bay, thereby triggering a scenario action that
(for instance) sends an e-mail message to the new user.
This chapter discusses how to create Web services that send JMS messages, and how to configure components
to listen for these messages. For more information about JMS and Patch Bay, see the Dynamo Message System
chapter of the ATG Programming Guide.
Using the JMS Message Web Service Wizard
To create a Web service that sends a JMS message, you use the Web Service Creation Wizard, just as you do
for Web services that invoke Nucleus methods. On the first screen of the wizard, however, you click the JMS
Message Web Service link (rather than the Component Method Web Service link). In this version of the
wizard, you do not select a Nucleus component and method; instead, the key selections are the message
type and the Patch Bay port name to use. The message type is the JMSType value for the message. This is
a String, stored in the message’s header, that identifies the kind of message it is. For example, a message of
JMSTypeatg.dps.PageVisit is sent when a site visitor displays a page.
For the port name, the wizard gives you two options, IndividualEvents and GlobalEvents. These are the
standard ports where the Scenario Manager listens for scenario events.
The names of the classes generated by the wizard are based on the JMS message type of the message. For
example, if you create a Web service that sends a message whose JMSType is atg.dps.PageVisit, the service
implementation interface is named SendPageVisitSEI, and the service implementation class is named
SendPageVisitSEIImpl.
Structure of a JMS Web Service
JMS Web services generated by the wizard are similar to Web services that call Nucleus methods. JMS services
expose a Nucleus method, but it is always the receiveObjectMessage() method of the component /atg/
20 2 Creating JMS Web Services
dynamo/messaging/MessageImporter. This method receives the message object and forwards it into Patch
Bay.
The receiveObjectMessage() method takes three parameters:
• the message object
• a String indicating the JMSType of the message
• a String indicating the Patch Bay port name to use
The Web service call itself takes only a single argument, the message object. The JMSType and port name are
hard-coded when you generate the Web service, and the service implementation class passes them (along
with the message object supplied by the client) to the receiveObjectMessage() method. This simplifies the
client’s task, because it does not need to be aware of either the JMSType or the port name.
For example, a Web service that sends a JMS message when a user views a page would be called like this:
public void sendPageVisit(atg.userprofiling.dms.PageVisitMessage a);
The service implementation class then calls the receiveObjectMessage() method like this:
messageImporter.receiveObjectMessage(a, "atg.dps.PageVisit", "IndividualEvents");
For information about calling Web services that send JMS messages from Java clients, see the Accessing ATG Web
Services from Java Clients (page 41) chapter. (Note that you cannot use the dynamic process described in
that chapter for calling these Web services.) For information about calling Web services that send JMS messages
from .NET clients, see the Accessing ATG Web Services from .NET Clients (page 53) chapter.
Patch Bay Configuration
The /atg/dynamo/messaging/MessageImporter component, whose receiveObjectMessage() method
is invoked by JMS Web services, is a Patch Bay message source. When a Web service invokes the method, the
message passed to that method is sent either to the destination patchbay:/sqldms/MessageImporter/
IndividualEvents or to patchbay:/sqldms/MessageImporter/CollectiveEvents, depending on the
message type.
The standard Patch Bay configuration file, /atg/dynamo/messaging/dynamoMessagingSystem.xml,
includes the necessary declarations for the message source and destinations:
<message-source> <nucleus-name> /atg/dynamo/messaging/MessageImporter </nucleus-name>
<output-port> <port-name> IndividualEvents </port-name>
2 Creating JMS Web Services 21
<output-destination> <destination-name> patchbay:/sqldms/MessageImporter/IndividualEvents </destination-name> <destination-type> Topic </destination-type> </output-destination> </output-port> <output-port> <port-name> GlobalEvents </port-name> <output-destination> <destination-name> patchbay:/sqldms/MessageImporter/CollectiveEvents </destination-name> <destination-type> Queue </destination-type> </output-destination> </output-port></message-source>
The Scenario Manager is a message sink configured to receive messages from these destinations. This
configuration occurs in two places:
• In the standard Patch Bay configuration file, the Scenario Manager is configured to receive individual scenario
events from the destination patchbay:/sqldms/MessageImporter/IndividualEvents.
• In the /atg/dynamo/messaging/dynamoMessagingSystemDSSGlobal.xml file, the Scenario Manager is
configured to receive global scenario events from the destination patchbay:/sqldms/MessageImporter/
CollectiveEvents.
You can configure other message sinks to receive messages from the patchbay:/sqldms/MessageImporter/
IndividualEvents destination by declaring them in the dynamoMessagingSystem.xml file. Note, however,
that you cannot configure other sinks to receive messages from patchbay:/sqldms/MessageImporter/
CollectiveEvents. This destination is a queue, used by global Scenario Managers only; adding sinks to this
destination may interfere with the global Scenario Managers receiving messages. If you want another message
sink to receive these messages, configure an additional destination for MessageImporter to send global
scenario events to, and configure your sink to listen to that destination instead.
3 Creating Repository Web Services 23
3 Creating Repository Web Services
The ATG Dynamo Administration interface provides an easy, browser-based way to create Web services
based on repository items. This Repository Web Service wizard is part of the Web Service Administration user
interface, which is introduced in the Web Service Creation Wizard (page 7) section of the Creating Custom Web
Services (page 5) chapter. You can use the Repository Web Service wizard to create Web services that add,
remove, update, or get a complete repository item, or a single property of a repository item.
Using the Repository Web Service Wizard
To use the Repository Web Service wizard to create a repository Web service:
1. Open the ATG Dynamo Administration interface and navigate to the Web Service Administration > Web
Service Creation Wizard > Repository Web Service page.
2. Identify the repository component that the Web service should access. You can do this in one of two ways.
The Create Repository Web Service page displays a text field in which you can enter the Nucleus address
of the repository component and click the Submit button. The Create Repository Web Service page also
displays a list of all repository components that are registered in the initialRepositories property of the
/atg/registry/ContentRepositories component. You can select a repository component by clicking
the link with the Nucleus address of the repository component.
3. The next page, with the heading Select item descriptor, displays all of the item descriptors in the repository
component you selected. Click the link for the item descriptor you want to expose in your Web service.
4. The next page, with the heading Select Method, displays the methods that are available for the item
descriptor you selected. For example, if the item descriptor is mutable, the following methods are available:
add
remove
update
get
The Select Method page also allows you to create a Web service for a specific property. The page displays a
list of links for each of the properties of the item descriptor you selected. Click one of these property names to
create a Web service for an individual repository item property.
The property name link leads to a list of the Web service methods that are available for that repository item
property, as well as notes about the Web service limitations, if any, related to the repository item property.
See Repository Web Service Limitations (page 24) for more information.
Click the name of the method you want to expose in your Web service.
24 3 Creating Repository Web Services
5. In the EAR Name & Servlet Settings page, the Web Service Creation Wizard displays default names for the
EAR file and servlet to be created. You can modify the default names. You can also, if you choose, enter a
description for the servlet and a network hostname and port number for the Web service. If you leave the
fields blank, the values are dynamically assigned at runtime from the URL used for the WSDL file request. You
should generally leave these fields blank, unless you want to require the Web service to be accessed on a
specific server and port.
Enter any settings you want to change and click the Next button.
6. In the Enterprise & Web Application Settings page, the Web Service Creation Wizard displays default
names for the enterprise application and Web application to be created. You can modify the default names.
You can also, if you choose, enter a description for the enterprise application and Web application.
Enter any settings you want to change and click the Next button.
7. The Session & Security Options page allows you to select one of the following three options for the Web
service:
8. Provide neither a session nor security constraints.
9. Provide a session, but no security constraints.
10.Provide both a session and security constraints.
If you choose the last option, the wizard then prompts you to select a security configuration. See the Creating
Custom Web Services (page 5) chapter for information about security configurations for Web services.
11.The Create EAR File page displays the parameter values you have selected for your Web service. Review
them, then click the Create EAR File button to create the Web service.
The Web service is created in an EAR file. You will find the EAR file in the <ATG9dir>/home directory, with the
name you selected in step 4.
To use the new Web service, you need to deploy it. See Deploying Web Services (page 15) in the Creating Web
Services chapter.
Repository Web Service Limitations
Because of the limitations inherent in Web services, repository items must generally be passed in XML form.
See the Repository to XML Data Binding (page 27) chapter for information about transforming repository
items into XML files and vice versa. In particular, you should bear in mind the following restrictions when you are
creating repository Web services:
get/setPropertyValue
1. Collection properties may not be set or gotten as a whole. Only elements of the collection may be set.
2. RepositoryItem properties are set or gotten as Strings in XML form
3. There is no type of service that can get or set sub-properties. You must act upon the actual RepositoryItem
you wish to read from or write to.
4. You cannot get or remove elements from a set or list. This is because in order to remove elements from either,
you need to provide the object to remove (or index, see below), and a Web service cannot guarantee that
that object is of a type that can be transformed from XML into a Java object.
3 Creating Repository Web Services 25
5. You cannot get or set a property of a type that corresponds to a Java primitive. For example, you cannot get
or set a java.lang.Integer or a java.lang.Boolean.
6. You cannot get or set a property of a non-simple type, other than atg.repository.RepositoryItem. This
includes types such as java.util.Timestamp and java.sql.Date. Note, however, that if you retrieve a
Date property, a java.util.Calendar will be returned.
7. You cannot get a property that is not readable, or set a property that is not writable.
addItem
The item to be added must be supplied in XML form.
updateItem
1. The item to be updated must be supplied in XML form.
2. By default, when a repository item is passed into the Web service, the existing RepositoryItem is found by
matching repository IDs. We determine the value of the repository ID from the top-level XML element in the
instance document, and then find a repository item with a matching ID.
removeItem
Users must pass in only the repository ID of the item to be removed.
Modifying Repository Web Services
Note that when you create a repository Web service using the Web Service Creation Wizard, the component
path of the repository, the item descriptor name and, if applicable, the property name, are all hard coded in the
generated Web service. If any of these variables is changed, the Web service will need to be regenerated.
Please note that the repository name is not taken into consideration when naming the Web service. Only the
item descriptor name and, if applicable, property name, is used to name a service. This means that if you are
generating Web services for two or more repositories with the same item descriptor names, you should consider
placing them into different WAR files, or giving them different servlet URLs.
RepositoryService Class
The atg.repository.RepositoryService class contains many methods that perform basic Repository
operations, independent of any particular repository implementation or instance. Such operations include
getting, adding, removing and updating a repository item, setting and getting properties of repository items,
and performing queries for repository items using RQL. Using the Web service generator, you can directly make
some of these methods into Web services by simply clicking a form submit button.
Some others of these methods are too generic to be made available as a Web service without limiting the
types of the inputs or outputs. For example, the method setPropertyValue takes a java.lang.Object as
a method argument for the property value. Since Web services don’t allow java.lang.Object as an input
(or output), this method cannot be used as a Web service in this form. However, we can restrict the type of this
26 3 Creating Repository Web Services
argument using the code generator template functionality, so when the Web service is generated, the outward-
facing method will be strongly typed based on the property being set, and can simply call through to the more
generic setPropertyValue method in the body of the Web service. The RepositoryService class has the
following properties:
Property Name Type Description
transactionManager javax.transaction.
TransactionManager
The service that manages any
transactions that are used to execute
repository methods on this instance.
mappingManager atg.repository.xml.
ItemDescriptorMappingManager
The component that manages mapping
files based on repository and item
descriptor name combinations.
For any methods that return a
RepositoryItem, this service will be
consulted to retrieve mapping files to
use when transforming these items
into XML. See Mapping Files and XML
Schemas (page 27) in the Repository
to XML Data Binding chapter for more
information abut mapping files and the
ItemDescriptorMappingManager
class.
xmlGetService atg.repository.xml.
GetService
The service that knows how to turn
RepositoryItems into XML.
xmlAddService atg.repository.xml.
AddService
The service that knows how to add
RepositoryItems in XML format to a
repository.
xmlUpdateService atg.repository.xml.
UpdateService
The service that knows how to take
RepositoryItems in XML format and
update them in their corresponding
repositories.
For information about the XML service properties, see Repository Operations (page 35) in the Repository to
XML Data Binding chapter.
4 Repository to XML Data Binding 27
4 Repository to XML Data Binding
One of the key aspects of integrating the ATG platform with a remote system is sharing data between the two
systems. Data sharing and synchronization are often complex, because the two systems may store their data in
dissimilar formats. The ATG platform data is typically stored in a Dynamo repository, which handles the mapping
of data in Java objects to the underlying data store (such as a SQL database).
The ATG Integration Framework includes a data binding facility for reading and writing data between a
repository and XML documents. Using this facility, you can write out repository data to XML documents that can
then be read into a remote system, or read data into a repository from XML documents that store data from a
remote system. A key aspect of this system is the use of mapping files to specify the data to include or exclude,
and to map the names of repository properties to the names used by the remote system. The data binding
facility also includes tools for generating XML Schemas that describe the structure of data in a repository, and to
use these XML Schemas to validate the data written out from or read into the repository.
The data binding facility provides services that perform these four operations with repository items:
• Getting items (retrieving items from a repository and writing them out to XML documents)
• Adding items (creating new items in a repository from data in XML documents)
• Updating items (modifying existing items using data in XML documents)
• Removing items (deleting items as indicated in XML documents)
This chapter discusses:
Mapping Files and XML Schemas (page 27)
Repository Operations (page 35)
Note that the classes described in this chapter work only with repositories included in the
initialRepositories property of the /atg/registry/ContentRepositories component.
Mapping Files and XML Schemas
In addition to the XML instance documents that store the actual data, data binding uses two other types of
documents:
• Mapping files control which data is exchanged between system, and which data is omitted.
• XML Schemas describe the structure of the data, and can be used to validate XML instance documents.
28 4 Repository to XML Data Binding
Mapping Files
When you exchange data between the ATG platform and a remote system, you will typically want to exclude
certain data. For example, an the ATG platform profile usually includes Dynamo-specific information about
scenarios.
When you create an XML instance document from data in a repository, Dynamo includes and excludes certain
properties by default:
• If a property is readable and does not point to another item descriptor, it is included.
• If a property is readable, points to another item descriptor, and its cascade attribute is set to "delete", it is
included.
• All other properties are excluded.
For more information about the default inclusion rules, see the isIncludeProperty() method of the
atg.repository.xml.RepositoryXMLTools class in the ATG API Reference. RepositoryXMLTools is a
utilities class with various methods for encoding and decoding item descriptors, property names, and mapping
files to and from XML-compatible namespaces and identifiers.
If you want more explicit control over the properties that are written out, you can use a mapping file. A mapping
file specifies what properties to include or exclude when moving data between a repository and an XML
instance document, and provides a way to map the names of Dynamo properties to their equivalents in a
remote system. For example, a Dynamo profile might have an email property that stores the same information
as the Email_Address attribute on another system.
The following is the Document Type Definition (DTD) for mapping files:
<!--This is the XML DTD for ItemDescriptorMapping-->
<!--
Specifies what properties in an item-descriptor should be included inanother datamodel. A given mapping file gives the ability to
- control what properties are included/excluded from the datamodel - control how names in one model relate to names in another model
-->
<!--Defines the mapping for a given item-descriptor. The name and repositoryproperty are required properties. The name property corresponds to thename of a given item-descriptor. The repository should be the Nucleuspath to a particular repository. For example, if an item-descriptor mappingwas going to point to the the ProfileAdapterRepository located at/atg/userprofiling/ProfileAdapterRepository Nucleus path, then the repositoryproperty should be the string "/atg/userprofiling/ProfileAdapterRepository".The default-include exists to indicate whether or not properties that areassociated with this item-descriptor should be included by default or not.This property defaults to true. So, if a property is does not explicitlyappear as a child property element, it is assumed to be included in thedata model to be exported.-->
4 Repository to XML Data Binding 29
<!ELEMENT item-descriptor (property*)>
<!ATTLIST item-descriptor repository-path CDATA #IMPLIED name CDATA #IMPLIED default-include (true | false) #IMPLIED>
<!--A property element controls two aspects of including a property in a givenmapping; whether the property should be included or not and what thetargetName for the target datamodel should be. The name attribute correspondsto the name of a property defined for a given item-descriptor. The includeattribute is optional. If it is not specified, the value is obtained from thedefault-include value of the enclosing item-descriptor.--><!ELEMENT property (item-descriptor*)>
<!ATTLIST property name CDATA #REQUIRED include (true | false) #IMPLIED targetName CDATA #IMPLIED>
Sample Mapping File
The following is a sample mapping file for the Dynamo profile repository:
<!DOCTYPE item-descriptor SYSTEM "http://www.atg.com/dtds/databinding/itemDescriptorMapping_1.0.dtd"><item-descriptor repository-path="/atg/userprofiling/ProfileAdapterRepository" name="user" default-include="true"> <property name="homeAddress" include="true"> <item-descriptor repository-path="/atg/userprofiling/ProfileAdapterRepository" name="contactInfo" default-include="false"> </item-descriptor> </property> <property name="slotInstances" include="false"/> <property name="scenarioInstances" include="false"/> <property name="mailings" include="false"/> <property name="scenarioValues" include="false"/> <property name="firstName" targetName="first_name"/></item-descriptor>
The data binding services all work with a single item descriptor and its properties (including any other item
descriptors that are properties of the main item descriptor). The mapping file uses the item-descriptor tag to
specify the repository and item descriptor that the mapping file is associated with:
<item-descriptor repository-path="/atg/userprofiling/ProfileAdapterRepository" name="user" default-include="true">
30 4 Repository to XML Data Binding
The default-include attribute specifies whether the item’s properties should be included or excluded by
default. This value can be overridden for individual properties. In this mapping file, various scenario-related
properties are excluded:
<property name="slotInstances" include="false"/><property name="scenarioInstances" include="false"/><property name="mailings" include="false"/><property name="scenarioValues" include="false"/>
If a property is an item descriptor, there must be an item-descriptor tag inside the property tag. For
example, the homeAddress property points to a contactInfo item descriptor:
<property name="homeAddress" include="true"> <item-descriptor repository-path="/atg/userprofiling/ProfileAdapterRepository" name="contactInfo" default-include="false"> </item-descriptor> </property>
Note that the item-descriptor tag for contactInfo can have property tags within it. The nesting of
property tags and item-descriptor tags must reflect the hierarchy of the item descriptors in the repository.
If you do not include a property tag for a property that points to an item descriptor (such as the homeAddress
property shown above), the ATG platform uses the default inclusion rules for determining which properties of
that item descriptor to include.
Finally, the property tag has an optional targetName attribute for mapping the property name to its
corresponding name in the remote system:
<property name="firstName" targetName="first_name"/>
Managing Mapping Files for Repository Item Descriptors
The ATG platform includes two classes that help identify the appropriate mapping file for each item descriptor
that you want to use with the repository2xml data binding facility. These classes are used by Web service clients:
atg.repository.xml.ItemDescriptorMappingatg.repository.xml.ItemDescriptorMappingManager
ItemDescriptorMapping
An ItemDescriptorMapping is a simple bean that holds information about relationships between repository
item descriptors and mapping files. The mapping files describe what properties are to be exposed when
an item from that item descriptor is to be transformed into XML. Each ItemDescriptorMapping pertains
to exactly one repository: for example, you would have a UserProfileItemDescriptorMapping, or a
PromotionItemDescriptorMapping component, each of which would provide a list of item descriptor names
from the corresponding repository and their corresponding mapping files.
An ItemDescriptorMapping contains only three properties:
4 Repository to XML Data Binding 31
Property Name Type Description
repositoryPath java.lang.String The path to the repository
supported by this
ItemDescriptorMapping. This is a
read-only property
repository atg.repository.Repository The path to the repository
supported by this
ItemDescriptorMapping.
Similar to repositoryPath but
this property will resolve to an
actual Repository instance, and is
writeable.
itemDescriptorMapping java.util.Map A map where the keys are item
descriptor names and the values are
locations of mapping files, relative
to the configuration path, which
provide rules for how an item of
the keyed item descriptor name
appears in XML format
Here is an example properties file for an ItemDescriptorMapping that supports the profile repository:
$class=atg.repository.xml.ItemDescriptorMappingrepository=/atg/userprofiling/ProfileAdapterRepositoryitemDescriptorMapping=\ user=/atg/userprofiling/userMapping.xml,\ contactInfo=/atg/userprofiling/contactInfoMapping.xml
Here we see the there are two entries in the itemDescriptorMapping property, one for the user item
descriptor, and one for the contactInfo item descriptor.
Whenever an entry is added to the itemDescriptorMapping property, whether through a properties file,
or directly in code, the ItemDescriptorMapping checks to make sure that the key of the entry, the item
descriptor name, resolves to an actual item descriptor of the repository this service is configured to support. If
any item descriptor name does not resolve, a RepositoryException is thrown.
By themselves, ItemDescriptorMappings don’t do any work. They simply hold state. In order to put them to
work, you must add them to the ItemDescriptorMappingManager, described below.
ItemDescriptorMappingManager
Class: atg.repository.xml.ItemDescriptorMappingManager
Component: /atg/repository/xml/ItemDescriptorMappingManager
Module: DAS
The ItemDescriptorMappingManager serves as a registry of ItemDescriptorMappings. It is through this
service that you obtain mapping files for all repository and item descriptor combinations. The mapping files are
registered in the itemDescriptorMappings property of the ItemDescriptorMappingManager component:
32 4 Repository to XML Data Binding
Property Name Type Description
itemDescriptorMappings atg.repository.xml.
ItemDescriptorMapping[]
An array of
ItemDescriptorMapping
components. When a user calls
methods to retrieve mapping files,
this component sifts through the
itemDescriptorMappings to
determine the correct mapping.
Here is an example properties file:
$class=atg.repository.xml.ItemDescriptorMappingManageritemDescriptorMappings=\ /atg/userprofiling/UserProfileItemMapping,\ /atg/userprofiling/ContactInfoItemMapping
The following ItemDescriptorMappingManager methods can be used to retrieve mapping files:
getMappingFileName(String pRepositoryPath, String pItemDescriptorName)
Using the given repository path and item descriptor name, returns the mapping file for that given path:name
combination, or null if none exists.
getMappingFileName(Repository pRepository, String pItemDescriptorName)
Using the given repository and item descriptor name, returns the mapping file for that given repository:name
combination, or null if none exists.
When you use the atg.repository.xml.GetService to get repository items in XML form, you can
pass along a mapping file name using these ItemDescriptorMappingManager methods. Using the
ItemDescriptorMappingManager, you can centralize all mapping files in one component for all item
descriptors, and just call that to determine which mapping file to use for a given item descriptor.
XML Schemas
The ATG platform provides tools for creating and working with XML Schemas for the XML documents written
and read by the various data binding services. XML Schema is a schema language for XML that describes and
restricts what a particular XML instance document might look like. An XML document can be validated against
an XML Schema to check that it conforms to that Schema. Additionally, many developer tools make use of XML
Schemas. For example, some tools provide a visual representation of XML Schemas to allow mapping from one
XML Schema to another.
Generating XML Schemas
The ATG platform provides a command-line tool that generates an XML Schema for a given item descriptor. The
XML generated by the Get data binding service conforms to this Schema. Similarly, the XML Schema describes
an instance document that is capable of being processed by the Add, Update, or Remove service.
The command-line tool is named generateXMLSchema.sh (on Unix) or generateXMLSchema.bat (on
Windows) and is found in the <ATG9dir>/home/bin directory. The following table lists the arguments that can
be supplied to this command:
4 Repository to XML Data Binding 33
-repository Nucleus path to the repository containing the item descriptor that the XML
Schema is being generated for. Required.
-itemDescriptor Name of the item-descriptor that the XML Schema is being generated for.
Required.
-outputDirectory Specifies a directory to save the XML Schema to. This directory is in addition
to the directory specified by the XMLSchemaFileDirectory property of the
XMLSchemaManager. Not required.
-saveSchemas If set to true, then the Schemas will be saved via the configured
XMLSchemaManager. If omitted, defaults to true.
-mappingFile Specifies the mapping file to use. Not required.
-schemaGenerator Nucleus path to the Schema Generator component. If omitted, defaults to /atg/
repository/xml/SchemaGenerator.
-m Specifies the set of modules to use in the repository definition. Required.
-help Prints out a usage message. Not required.
Example
The following command generates an XML Schema for the user item descriptor of the default Dynamo profile
repository, using the properties defined in the repository definition file for the DSSJ2EEDemo application
module (and the modules required by the DSSJ2EEDemo module):
generateXMLSchema -m DSSJ2EEDemo –repository /atg/userprofiling/ProfileAdapterRepository -itemDescriptor user
The generated XML Schema is saved by the Schema Manager specified by the schemaManager property
of the Schema Generator component. The default Schema Generator is the /atg/repository/xml/
SchemaGenerator component, and its schemaManager property points by default to the /atg/repository/
xml/SchemaManager component. Note that if the user item descriptor contains other item descriptors as
properties, the generated Schema will reflect these other item descriptors as well.
To save the Schema to the current working directory in addition to the directory determined by the
XMLSchemaFileDirectory property of the Schema Manager:
generateXMLSchema -m DSSJ2EEDemo –repository /atg/userprofiling/ProfileAdapterRepository -itemDescriptor user -outputDirectory .
Managing Schemas and Mapping Files
As mentioned above, the default Schema Generator has a schemaManager property that points to the
/atg/repository/xml/SchemaManager component. In addition, each of the data binding service
components (described below) has an XMLSchemaManager property that points to this SchemaManager
34 4 Repository to XML Data Binding
component. This component is of class atg.repository.xml.XMLSchemaManager. This class, which extends
atg.repository.databinding.MappingManager, manages XML Schemas and mapping files. For example,
this class has mappingFileDirectories and XMLSchemaFileDirectory properties that specify the
directories where mapping files and Schemas are stored. Note that Schemas must have the extension .xsd and
mapping files must have the extension .xml.
For example, suppose you want to generate an XML Schema and specify a mapping file to use. The command
would look something like this:
generateXMLSchema -m DSSJ2EEDemo –repository /atg/userprofiling/ProfileAdapterRepository -itemDescriptor user -mappingFile profileMapping.xml
Notice that only the name of the mapping file is specified, not the entire pathname. The Schema Manager’s
mappingFileDirectories property points to the directories where the mapping file should be stored.
PropertyElementNameSeparator
The repository2xml feature specifies a separator character, which functions to separate a property name
from the name of its item descriptor. By default, this separator character is . (dot). The default separator
character may not work for you if, for example, you use composite repository IDs that also use the . (dot)
character to separate elements of the repository ID. You can specify a different separator character in the
propertyElementNameSeparator property of the /atg/repository/xml/RepositoryXMLTools
component.
Item References
In a repository schema, a map, set, list, or array property can point to a single other item using the itemRef
attribute. The value assigned to the itemRef attribute concatenates the item descriptor name, the property
element separator, and the repository ID. In the following example, the item descriptor name is role, the
property element separator is . (dot) and the repository ID is 2900004:
<user:itemRef itemRef="role.2900004"/>
The following is a more extended example, showing the context for the itemRef attribute:
<user:user xmlns:user=http://www.atg.com/ns/profileMapping/UserProfiles/user xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xsi:schemaLocation="http://www.atg.com/ns/profileMapping/UserProfiles/user profileMapping+UserProfiles+user.xsd " ID="user747"> <user:homeAddress itemRef="contactInfo.1040001"/> <user:roles> <user:itemRef itemRef="role.2900004"/> <user:itemRef itemRef="role.3000008"/> </user:roles></user:user>
4 Repository to XML Data Binding 35
Repository Operations
The atg.repository.xml package includes a service class for each of the four repository operations
supported by the data binding facility. The following table lists these classes and the Nucleus instances included
in Dynamo:
Class Nucleus component
atg.repository.xml.GetService /atg/repository/xml/GetService
atg.repository.xml.AddService /atg/repository/xml/AddService
atg.repository.xml.UpdateService /atg/repository/xml/UpdateService
atg.repository.xml.RemoveService /atg/repository/xml/RemoveService
The following sections discuss each of these classes and the operations they perform. See the entries for these
classes in the ATG API Reference for more information.
Getting Repository Items
You use getItemAsXML() method of the atg.repository.xml.GetService class to create XML documents
from repository items. This method takes a repository item as an input argument and returns a String
containing an XML representation of this item. If you write out this String (e.g., to a file), be sure to use the
same character encoding that the repository uses.
Some versions of the getItemAsXML() method take additional inputs for specifying a String array of the
names of the properties to write out or a String containing the name of the mapping file to use. If you
supply only a repository item as input, the method uses the default inclusion rules (described in the Mapping
Files (page 28) section) to determine which properties to include.
By default, GetService writes out an XML document as a single line, because it is intended to be machine-
readable. If you want the generated XML to be human-readable, set the indentXMLOutput property of the
GetService component to true. The resulting XML will have appropriate line breaks.
Example
Suppose you want to generate XML for a user profile, based on a mapping file named profileMapping.xml.
The following code finds the user repository item whose ID is "user747" and generates an XML representation
of it:
RepositoryItem userItem = getProfileRepository().getItem("user747", "user");String userAsXML = GetService.getItemAsXML(userItem,"profileMapping.xml");
The following is sample output from this code. The data represents the profile of the user sandy in the Quincy
Funds demo:
<user:user xmlns:user="http://www.atg.com/ns/profileMapping/UserProfiles/user" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
36 4 Repository to XML Data Binding
xsi:schemaLocation="http://www.atg.com/ns/profileMapping/UserProfiles/user profileMapping+UserProfiles+user.xsd " ID="user747"> <user:securityStatus>0</user:securityStatus> <user:actualGoals>long-term</user:actualGoals> <user:gender>female</user:gender> <user:fundShares> <user:integer>500</user:integer> <user:integer>220</user:integer> <user:integer>180</user:integer> <user:integer>260</user:integer> </user:fundShares> <user:goals>short-term</user:goals> <user:dateOfBirth>1976-12-09</user:dateOfBirth> <user:pubPrivileges>none</user:pubPrivileges> <user:homeAddress> <user:homeAddresscontactInfo ID="contactInfo747"/> </user:homeAddress> <user:numberNewsItems>4</user:numberNewsItems> <user:strategy>conservative</user:strategy> <user:locale>en_US</user:locale> <user:lastActivity>2002-08-14T18:33:49.604</user:lastActivity> <user:aggressiveIndex>5</user:aggressiveIndex> <user:lastName>Pieta</user:lastName> <user:actualStrategy>conservative</user:actualStrategy> <user:interests> <user:string>tax</user:string> <user:string>international</user:string> </user:interests> <user:id>747</user:id> <user:fundList> <user:string>/repositories/Funds/en_US/overseas.xml</user:string> <user:string>/repositories/Funds/en_US/moneymarket.xml</user:string> <user:string>/repositories/Funds/en_US/growth.xml</user:string> <user:string>/repositories/Funds/en_US/growthincome.xml</user:string> </user:fundList> <user:email>[email protected]</user:email> <user:password>d686a53fb86a6c31fa6faa1d9333267e</user:password> <user:registrationDate>1999-04-15T00:00:00.0</user:registrationDate> <user:userType>investor</user:userType> <user:member>true</user:member> <user:brokerId>734</user:brokerId> <user:numberFeatureItems>3</user:numberFeatureItems> <user:login>sandy</user:login> <user:guests>false</user:guests> <user:brokers>false</user:brokers> <user:investors>true</user:investors></user:user>
Namespaces
Notice that information about the XML Schema for this data is included in the user:user tag at the beginning
of the document:
xsi:schemaLocation="http://www.atg.com/ns/profileMapping/UserProfiles/user profileMapping+UserProfiles+user.xsd "
The xsi:schemaLocation attribute specifies the URL and name of the Schema file. The Schema
filename (profileMapping+UserProfiles+user.xsd) is determined by the name of the mapping file
4 Repository to XML Data Binding 37
(profileMapping.xml), the name of the repository (UserProfiles), and the item descriptor (user). If no
mapping file is used to create the document, the Schema filename indicates the repository and item descriptor.
If you want the Schema filename to include the entire pathname, set the appendRelativeSchemaLocation
property of the GetService component to true. This is especially important if you’re using an external Schema
verification tool, which will generally need the complete pathname to find the Schema file.
If you use a mapping file when you create an instance document, you should be sure to supply the name of this
mapping file to the generateXMLSchema command (using the –mappingFile argument) when you generate
the Schema. Otherwise the actual Schema filename will not match the name in the xsi:schemaLocation
tag, and the Schema may not accurately reflect the data in the instance document; as a result, you may not
be able to validate the data when reading it into a remote system (or reading it back into Dynamo using
AddService). Note also that if your call to getItemAsXML() includes an input argument that specifies the
names of properties to write out, the Schema will not accurately reflect the data in the instance document, so
validation will not be possible.
To avoid any conflict between tag names, the XML tags in the generated instance document are named
using the convention itemType:propertyName; for example the user:userType tag stores the value
of the userType property of the user item type. If the addItemTypeToPropertyNames property of the
RepositoryXMLTools component that GetService points to is set to true, the tags are named using the
convention itemType:itemType.propertyName; in this case, the tag name would be user:user.userType.
By default addItemTypeToPropertyNames is set to true, because the resulting XML is less likely to result in
naming collisions.
Adding Repository Items
You use the addItem() method of the atg.repository.xml.AddService class to create new
repository items from XML documents. This method takes an XML document as an input argument and
returns a repository item. The XML document can be in the form of a String, a java.io.Reader, or a
java.io.InputStream. The method examines the schemaLocation attribute in the XML document to
determine if there is a mapping file associated with the document. Some versions of the method take additional
arguments for specifying how to handle missing or empty tags, and whether the data should be validated
against a Schema.
For some examples of how a repository item might look in XML document form, see the <ATG9dir>/RL/
Example/j2ee-apps/example/web-app/public directory. The Repository Loader (RL) module also
includes a page you can use to generate XML documents from existing repository items. This page is located at
<ATG9dir>/RL/Example/j2ee-apps/example/web-app/itemAsXml.jsp.
Note that addItem() cannot create new read-only elements in a repository. By default, any data in the instance
document that corresponds to a read-only element in the repository is silently ignored. If you want addItem()
to log a warning each time it skips a read-only element, set the logWarningOnReadOnly property of the
AddService component to true.
Validating the Data
The addItem() method can optionally validate the data in an XML instance document against the Schema
specified in the instance document. Validation is enabled or disabled by the validate property of the
AddService component. By default, this property is set to false, because validation slows down processing of
the document. To enable validation, set the validate property to true.
The addItem() method can also take a Boolean argument to specify whether to validate the document. The
value of this argument overrides the validate property. If you do not specify this argument, addItem() uses
the validate property to determine whether to validate the document.
38 4 Repository to XML Data Binding
If you are confident that your data is valid, you can disable validation, and the instance document will be
processed more quickly. However, if the data turns out to be invalid, the invalid data may be written to the
repository. If you enable validation and the data is invalid, addItem() does not write the contents of the
instance document to the repository.
Updating Repository Items
You use the updateItem() method of the atg.repository.xml.UpdateService class to modify a
repository item. For example, the following instance document updates a user’s email address:
<user:user xmlns:user="http://www.atg.com/ns/UserProfiles/user" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.atg.com/ns/UserProfiles/user UserProfiles+user.xsd " ID="user747"> <user:user.emailAddress>[email protected]</user:user.emailAddress></user:user>
The updateItem() method can optionally validate the instance document against the specified Schema.
The logic for this is similar to the AddService.addItem() method: the UpdateService component has
a validate property whose default value is false, and the updateItem() method can take a Boolean
argument that overrides the value of the validate property.
Selecting the Item to Update
There are two ways to select the item to update:
• You can specify the item explicitly when you call updateItem().
• You can specify a set of match properties, and updateItem() selects the item whose values match the
corresponding values in the instance document.
For example, the login property is often used for matching, because it is unique to a specific user item and its
value does not change. The following XML instance document could be used to select the item and then update
its emailAddress property:
<user:user xmlns:user="http://www.atg.com/ns/UserProfiles/user" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.atg.com/ns/UserProfiles/user UserProfiles+user.xsd " ID="user747"> <user:user.emailAddress>[email protected]</user:user.emailAddress> <user:user.login>sandy</user:user.login></user:user>
The application would then use the following code to update the user repository item whose login value is
sandy (assuming the inputXML String contains the instance document shown above):
String[] matchProperties = {"login"};RepositoryItem updatedItem = UpdateService.updateItem(inputXML, matchProperties);
Note that UpdateService determines the repository and item type from the namespace of the instance
document. For more information, see Namespaces (page 36) in the Getting Repository Items (page 35)
section.
4 Repository to XML Data Binding 39
The matchProperties array can contain any number of property names. If the value of each repository item
property named in matchProperties matches its corresponding attribute in the XML instance document, the
item is selected for update. All of the specified properties must match for the item to be selected; for example, if
matchProperties lists login and lastName properties, the values of both properties must match. If multiple
items are selected, an exception is thrown and no update occurs.
Matching is limited to top-level properties of the repository item. Subproperties (such as properties of other
repository items) cannot be matched. So, for example, if a user item has a lastName property that is a String,
you can include lastName in matchProperties; but if auser item has a shippingAddress property that is
another repository item, you cannot include, say, shippingAddress.city in matchProperties.
If a property has been mapped to a different name in the instance document, the name to match on is the
property name used in the repository, not the instance document. For example, suppose you use a mapping file
to map a user item’s dateOfBirth property to the name birthday, like this:
<item-descriptor repository-path="/atg/userprofiling/ProfileAdapterRepository" name="user" default-include="true"> <property name="dateOfBirth" targetName="birthday"/>
The corresponding instance document might look like this:
<user:user xmlns:user="http://www.atg.com/ns/UserProfiles/user" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.atg.com/ns/UserProfiles/user UserProfiles+user.xsd " ID="user747"> <user:user.birthday>02-06-1975</user:user.birthday></user:user>
To specify this property in matchProperties, you use the name of the property as it is defined in the repository
(dateOfBirth), not the target name (birthday). For example:
String[] matchProperties = {"dateOfBirth"};
You can configure the UpdateService to add a repository item if an attempt to update does not find a match.
If you want the UpdateService to add items when no items are matched, set the addWhenNoMatchedItems
property of the UpdateService to true.
If the property being updated is a simple type (such as a String), then its value is updated by the
UpdateService. When the property being updated is a list, map or array, then the old value is replaced by the
new value. The new value is not appended to the old value. If the property being updated is an item descriptor,
then the appropriate fields of the existing item descriptors are updated.
repositoryId
The repositoryId attribute of an item can be used as a special match property. If the repositoryIdString
is passed to UpdateService as a match property, the service will determine the value of this attribute from the
top-level XML element in the instance document, and then find a repository item with a matching repository ID.
The following XML example uses the repositoryId attribute as a match property:
<user:user xmlns:user="http://www.atg.com/ns/UserProfiles/user" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
40 4 Repository to XML Data Binding
xsi:schemaLocation="http://www.atg.com/ns/UserProfiles/user UserProfiles+user.xsd " ID="user747" repositoryId="user707"> <user:user.emailAddress>[email protected]</user:user.emailAddress></user:user>
String[] matchProperties = {"repositoryId"};RepositoryItem updatedItem = UpdateService.updateItem(inputXML, matchProperties);
In this case, the UpdateService selects the user item whose repositoryId is "user707" from /atg/
userprofiling/ProfileAdapterRepository.
Note: Do not confuse with the repositoryId attribute, which identifies a repository item, with the ID attribute
used in the XML schema to identify an XML element. The repositoryId attribute and not the ID attribute is
used to identify which repository item to update.
Removing Repository Items
You use the removeItems() method of the atg.repository.xml.RemoveService class to delete repository
items specified in XML documents. This method takes an XML document in the form of a String array, a
java.io.Reader, or a java.io.inputStream.
Some versions of removeItems() take a matchProperties String array. Property matching for
RemoveService.removeItems() uses the same logic as UpdateService.updateItem(), except it is legal for multiple
repository items to be marked for deletion. For example, an instance document to remove all users whose date
of birth is 02-06-1975 would look like:
<user:user xmlns:user="http://www.atg.com/ns/UserProfiles/user" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.atg.com/ns/UserProfiles/user UserProfiles+user.xsd " ID="user747"> <user:user.dateOfBirth>02-06-1975</user:user.dateOfBirth></user:user>
The application then uses the following code to remove all the user repository items whose dateOfBirth value is
02-06-1975 (assuming the inputXML String contains the instance document shown above):
String[] matchProperties = {"dateOfBirth"};String[] removedItemIds = RemoveService.removeItem(inputXML,matchProperties);
The maximum number of matching items is specified by the maxSelectedItems property of RemoveService.
If the number of matching repository items exceeds this value, an exception is thrown. In the /atg/
repository/xml/RemoveService component, maxSelectedItems is set to 5 by default.
5 Accessing ATG Web Services from Java Clients 41
5 Accessing ATG Web Services from
Java Clients
The ATG platform permits external Java clients to access Nucleus methods by exposing them as ATG Web
services. Many such ATG Web services are included with the ATG platform, as are tools for creating custom
Web services. For a list of ATG Web services, see ATG Web Services (page 1). Java clients can execute those Web
services through calls that are translated into XML wrapped in SOAP, transmitted to the ATG platform, and
routed to the Nucleus method itself. Other ATG resources, such as JMS messages and RepositoryItems, can
also be exposed as ATG Web services.
The ATG implementation of Web services follows the standard Web service guidelines outlined by JAX-RPC 1.0
and SOAP 1.1 specifications. ATG recommends that you use Apache Axis 1.4 to create your Web service calls, and
this chapter includes code examples that assume you are using Axis.
This chapter aims to inform you how to call ATG Web services from an Axis client. Rather than provide a broad
discussion on how to use Axis, this chapter describes ATG-specific features and processes that you need to be
familiar with. Please see the Axis documentation for comprehensive instructions.
To access an ATG Web service, you need to be familiar with the following topics:
About ATG Web Services (page 41)
Before You Begin (page 43)
Writing a CookieContainer Class (page 43)
Calling ATG Web Services (page 45)
Creating a Serializer and Deserializer (page 48)
About ATG Web Services
For the most part, you call ATG Web services in the same way you call Web services elsewhere. While the general
process may not differ, it’s important that you are aware of these platform-specific features.
Security
The content you see as a response to a Web service call depends on your access privileges. When you login
using the loginUser Web service, you provide your user identity. If session sharing is enabled, all subsequent
Web service calls in that session are associated with that identity and related role.
42 5 Accessing ATG Web Services from Java Clients
For more information on loginUser, see the ATG Personalization Programming Guide. You may also want to
learn how other Web services handle the security information provided by loginUser. Such information exists
in the ATG Repository Guide and the ATG Commerce Programming Guide.
Transactions
When a client calls a Web service, the transactional behavior of the service is managed entirely on the server
side. The method that is exposed as a Web service can use standard transaction demarcation techniques, but
the calling client has no control over this.
There are some practical considerations you should be aware of. If a single Web service call attempts to perform
some operation, and the operation fails, the operation can be rolled back (provided that the Nucleus method
is demarcated properly). However, a transaction cannot span multiple Web service calls so if an operation
is performed by a sequence of Web service calls, and the final call fails, there is no way to roll back the steps
performed by the previous calls.
Sharing Sessions
When you create a Web service, you specify whether it should be executed within the context of an HTTP
session. Associating Web services with a session enables an application to maintain state across Web service
calls and to use login information for security purposes.
To allow multiple Web services to share a session, two things need to happen:
1. The Web service client must allow a session to be shared across certain Web service calls. To do this, the client
must pass a session cookie between calls.
2. The Web services themselves must support sessions. When you create custom Web services, the Web Service
Creation Wizard gives you the option of supporting sessions.
This chapter includes an example of a helper class that you can use to simplify cookie management. See Writing
a CookieContainer Class (page 43).
RepositoryItems
If your Web services access RepositoryItems, you need to provide a serializer and deserializer so the
RepositoryItem content can be interpreted by non-ATG systems. The following Web Services transmit content
that’s natively stored as RepositoryItems:
• getProfile
• getRepositoryItem
• performRQLQuery
• getOrderAsXML (Commerce users only)
• getOrdersAsXML (Commerce users only)
• getProductXMLById (Commerce users only)
• getProductXMLByDescription (Commerce users only)
• getProductXMLByRQL (Commerce users only)
• getProductSkusXML (Commerce users only)
5 Accessing ATG Web Services from Java Clients 43
• getPromotionsAsXML (Commerce users only)
The ATG platform includes several tools for working with RepositoryItems. To make a client able to serialize
and deserialize RepositoryItems, you need to translate the RepositoryItem class into a language that’s
native to your client. See Creating a Serializer and Deserializer (page 48) for more information.
Before You Begin
Before you can access a Web service, you need to make sure the ATG platform is ready for your call and Axis 1.4 is
configured:
1. Confirm that the application that includes the Web service is deployed on your application server and is
running. For more information, see Deploying Web Services (page 15).
2. Download Axis 1.4 from the Apache web site:
http://ws.apache.org/axis
3. Extract the contents of the Axis download file.
4. Add the axis libraries to your CLASSPATH.
See the Apache site for more information about using Axis.
Writing a CookieContainer Class
The following example shows a sample CookieContainer class. You can use this as a model for your own class.
Note that:
• This class relies on the Axis API. If you are using a different Java client, you will need to use the API for your
client.
• This class works with both static and dynamic Web service calls. (See Calling ATG Web Services (page 45).)
If you always make only one of these call types, your own CookieContainer class does not need to handle
both cases.
package com.example.webservice;
import org.apache.axis.MessageContext;import org.apache.axis.client.Call;import org.apache.axis.client.Stub;import org.apache.axis.transport.http.HTTPConstants;
/** * A class that can be passed between web service clients that keeps track of * the cookies received from the server. These cookies are then used by * subsequent web service client calls in order to ensure that session * state is maintained.**/public class CookieContainer{
44 5 Accessing ATG Web Services from Java Clients
//------------------------------------- // Member variables //-------------------------------------
/** Array of cookies from the Set-Cookie HTTP header **/ private String[] mCookies = null;
/** Array of cookies from the Set-Cookie2 HTTP header **/ private String[] mCookies2 = null;
//------------------------------------- // Methods //-------------------------------------
/** * Gets the cookies set by the Set-Cookie HTTP header * @return the cookies from the Set-Cookie HTTP header, which * may be null **/ public String[] getCookies() { return mCookies; }
/** * Gets the cookies set by the Set-Cookie2 HTTP header * @return the cookies from the Set-Cookie2 HTTP header, which * may be null **/ public String[] getCookies2() { return mCookies2; }
/** * Extracts the cookies from the given Axis MessageContext, and * sets the cookies and cookies2 properties from them. * @param pContext the Axis message context to examine. This * cannot be null **/ public void extractCookies(MessageContext pContext) { mCookies = (String[])pContext.getProperty (HTTPConstants.HEADER_COOKIE); mCookies2 = (String[])pContext.getProperty (HTTPConstants.HEADER_COOKIE2); }
/** * Extracts the cookies from the given Axis Call, and * sets the cookies and cookies2 properties from them. * @param pCall the Axis call to examine. This * cannot be null **/ public void extractCookies(Call pCall) { extractCookies(pCall.getMessageContext()); }
/** * Extracts the cookies from the given Axis Stub, and * sets the cookies and cookies2 properties from them. * @param pStub the Axis stub to examine. This * cannot be null
5 Accessing ATG Web Services from Java Clients 45
**/ public void extractCookies(Stub pStub) { extractCookies(pStub._getCall()); }
/** * Pushes the cookie values that are set on the instance to * the given Call * @param pCall the call to set the cookies on. This cannot be null **/ public void pushCookies(Call pCall) { if(mCookies != null) pCall.setProperty(HTTPConstants.HEADER_COOKIE, mCookies); if(mCookies2 != null) pCall.setProperty(HTTPConstants.HEADER_COOKIE2, mCookies2); }
/** * Pushes the cookie values that are set on the instance to * the given Stub * @param pStub the stub to set the cookies on. This cannot be null **/ public void pushCookies(Stub pStub) { if(mCookies != null) pStub._setProperty(HTTPConstants.HEADER_COOKIE, mCookies); if(mCookies2 != null) pStub._setProperty(HTTPConstants.HEADER_COOKIE2, mCookies2); }}
Calling ATG Web Services
When you call a Web service, you create resources that describe the Web service you want to call, its location,
and initial inputs. Axis then takes those resources and produces from them a SOAP message that it then sends to
the Web service itself.
There are two ways to create a Web service call:
• Use a client stub to create a static Web service call.
• Use the Dynamic Invocation Interface to create a dynamic Web service call.
The main distinction between the two processes is the data types they can handle. Because using Web services
requires that data be converted into several formats — from a native format into an XML representation of that
format back into the native form — it is important that you choose a process designed to work with the data
types accessed by the Web services you want to employ.
The static process can handle any data type regardless of whether it’s primitive, complex, object, or
non-standard. Non-standard types may require some extra effort as is the case when accessing ATG
RepositoryItems or JMS messages. The dynamic process, conversely, is limited to only working with object
versions of these data types (as permitted by SOAP 1.1):
• Boolean
46 5 Accessing ATG Web Services from Java Clients
• Byte
• Double
• Float
• Int
• Long
• Short
Some complex types such as Array, List, Set, and Map may be supported using the dynamic process in a
restricted way. See the JAX-RPC Specification for details on data type restrictions.
The subsequent sections describe how you would make a call to the loginUser ATG Web service following the
static and dynamic processes.
Creating a Call Using a Client Stub (Static)
When you create a call following the static method, you represent the server-side Web service architecture on
the client by creating a client stub and a client:
• The client stub describes the associated Web services resources as well as the remote procedure call that the
Web service executes.
• The client configures a particular Web service instance by specifying initial values and methods on various
Web services resources.
The call is constructed by compiling information from the client stub, client, and various other supporting
classes that hold static information.
For example, to create a static call to the loginUser Web service:
1. Create and compile the client stub, if one does not already exist for the Web service. See Creating and
Compiling a Client Stub (page 46) below.
2. Add the client stub to the CLASSPATH variable so the client stub is available to local Web services resources.
3. Create and compile the client. See Creating and Compiling a Client (page 47) below.
4. Use Axis to execute the Web service call:
loginStub.createUser(pProfileAsXML)
The format of this call is
clientStub.web_service(generated_web_Service_Call_instance)
Axis creates the XML message, wraps it in SOAP, and sends it via HTTP to the Web service location in the client
stub.
Creating and Compiling a Client Stub
The client stub describes the Web service method and supporting resources in a structure that’s familiar to the
client. Each Web service requires a stub for each client that executes it. You can reuse a stub for subsequent calls
5 Accessing ATG Web Services from Java Clients 47
so you only need to create it once. However, simultaneous calls to a Web service made by different threads will
require that a unique client stub instance exists for each thread.
To create and compile a client stub for the loginUser Web service:
1. Locate the active WSDL file via HTTP for the Web service you want to call. The URL is provided in with the
documentation that describes each Web Service:
• For Repository Web services, see the ATG Repository Guide.
• For Personalization Web services, see the ATG Personalization Programming Guide.
• For Commerce Web Services, see the ATG Commerce Programming Guide.
It’s important that you access the runtime and not the static version of the WSDL document. Assuming
that you included the modules holding the Web services you want to access when you assembled your
application, you should be able to download the runtime version of the WSDL.
2. Use the Axis WSDL-to-Java tool to generate the client stub based on the WSDL.
3. Compile the client stub.
Creating and Compiling a Client
A Web service client is a Java file that describes precisely what the Web service should do. It provides the actions
the Web service should commit and initial values.
If you want to enable Web services to share sessions, your code needs to pass cookies between calls.
The following example, which creates a static Web service call to the loginUser Web service, uses the
CookieContainer class shown in Writing a CookieContainer Class (page 43):
{ LoginUserSEIService loginService = new LoginUserSEIServiceLocator(); LoginUserSEI loginStub = loginService.getLoginUserSEIPort(); org.apache.axis.client.Stub axisStub = (org.apache.axis.client.Stub) loginStub; CookieContainer cookieContainer = new CookieContainer();
axisStub.setMaintainSession(true); // Don't allow XML elements to reference other XML elements axisStub._setPropertyValue(AxisEngine.PROP_DOMULTIREFS, new Boolean(false)); // Push cookies onto the Stub cookieContainer.pushCookies(stub);
String userId = loginStub.loginUser("bhavern", " xyo8bnif", false);
// Get cookies out of the Stub, and pass them to subsequent calls as needed cookieContainer.extractCookies(stub);}
Creating a Call Using the Dynamic Invocation Interface (Dynamic)
A dynamic Web service call holds all relevant information in one file, the client, which Axis converts directly into
the SOAP message. Essentially, the client you create is a Java version of the call itself, excluding some relative
values that are replaced with absolute ones at compile time.
Keep in mind that if you want to access a Web service that uses non-standard data types, you need to create
your Web service call following the static process. See Creating a Call Using a Client Stub (Static) (page 46).
48 5 Accessing ATG Web Services from Java Clients
If you want to enable Web services to share sessions, your code needs to pass cookies between calls. The
following example, which creates a dynamic Web service call to the loginUser Web service, uses the
CookieContainer class shown in Writing a CookieContainer Class (page 43):
Service service = new Service();Call call = (Call) service.createCall();
// Get a hold of a CookieContainer passed to this method/classCookieContainer cookieContainer = new CookieContainer();
// Push previous cookies (if any) to the new Call objectcookieContainer.pushCookies(call);call.setMaintainSession(true);
call.setTargetEndpointAddress(newjava.net.URL("http://hostname:port/userprofiling/usersession/loginUser/loginUser") );
// Don't allow XML elements to reference other XML elementscall.setProperty(AxisEngine.PROP_DOMULTIREFS,Boolean.FALSE)
call.addParameter("Login", org.apache.axis.Constants.XSD_STRING, javax.xml.rpc.ParameterMode.IN);call.addParameter("Password", org.apache.axis.Constants.XSD_STRING, javax.xml.rpc.ParameterMode.IN);call.addParameter("IsPasswordEncrypted", org.apache.axis.Constants.XSD_BOOLEAN, javax.xml.rpc.ParameterMode.IN);call.setReturnType(org.apache.axis.Constants.XSD_STRING);call.setOperationName(new QName("http://www.atg.com/webservices", "loginUser"));String userId = (String) call.invoke( new Object[] { "bhavern", "xyo8bnif", Boolean.FALSE } );
// Extract new cookies from the Call into the CookieContainer object,// which can then be passed to subsequent callscookieContainer.extractCookies(call);}
Creating a Serializer and Deserializer
When you want to use a Web service that accesses RepositoryItems, you can create a mechanism for
translating foreign content into different formats:
• A serializer will convert content from a native format into XML that will eventually undergo another
conversion into a RepositoryItem. You need to create a serializer for “set” operations in which the client
sends content to the Web service in the context of the call.
• A deserializer constructs XML content that was originally formatted as RepositoryItems into a native
content format. You need to create a deserializer for “get” operations in which a Web call returns content that
represents a RepositoryItem.
5 Accessing ATG Web Services from Java Clients 49
Both a serializer and a deserializer will need to understand the RepositoryItem schema. When you create the
XML schema and a mapping file, you’ll need some information about the Web service itself. You can find that
information in the sections that describe the Web service:
• For getProfile, see the ATG Personalization Programming Guide.
• For getOrderAsXML, getOrdersAsXML, getProductXMLById, getProductXMLByDescription,
getProductXMLByRQL, getProductSkusXML, getPromotionAsXML, see the ATG Commerce Programming
Guide.
• For Repository Web services , see the ATG Repository Guide.
Two Repository Web services, getRepositoryItem and performRQLQuery, require a serializer and deserializer,
but they can apply to any RepositoryItems you choose, which is different from the other Web services that
are only available to specific RepositorityItems and item descriptors.
The serializers and deserializers you create require a Repository schema, which you can create by following these
steps:
1. Create a Mapping file that determines which RepositoryItem properties will be captured by the Web
Service and returned by the call. See Creating a Mapping File (page 49).
2. Use the generateXMLSchema tool to convert the RepositoryItem class into a standard XML schema. See
Generating an XML Schema (page 50).
3. Insert a reference to the XML schema in your instance document, which is a document that represents an
instance of the Web service call. You complete this step when you configure the client stub; see Creating and
Compiling a Client Stub (page 46) for instructions.
Creating a Mapping File
If you were to create an XML schema that included all RepositoryItem properties, some content may not
be understood by standard deserializers and some may not conform to the XML 1.0 specification. Instead,
you create a mapping file that determines which properties, from the RepositoryItem's item descriptor,
to include or exclude from your XML schema. For instructions on how to create a mapping file, see Mapping
Files (page 28).
To create a mapping file, you need to know the properties defined by your item descriptor so you can decide
which of them ought to be represented in the XML schema. You can find the location of a Repository’s item
descriptor in the ATG platform Dynamo Administration UI:
1. In Dynamo Administration UI, click the Component Browser link.
2. Navigate to the Repository component that correlates to your Web service as indicated in the documentation
for your ATG Web service.
3. Click the See Property Descriptions link beside the item descriptor name. For the item descriptor name, see
the documentation for your ATG Web service.
This list that displays includes all properties that are available to the item descriptor based on the modules
that are currently running.
To make this XML schema compatible with the expectations of the resources that will use it, exclude the
following items from your XML schema:
1. RepositoryItem properties that accept primitive data types and may be null.
50 5 Accessing ATG Web Services from Java Clients
2. RepositoryItem properties that accept Maps, Lists, or Sets.
Generating an XML Schema
The generateXMLSchema is a script that takes a given Repository component and item descriptor as arguments
and produces an XML schema. For instructions on using this tools, see XML Schemas (page 32).
When you create an XML schema in support of a Web service, make sure that the same modules in the ATG
platform are running now as those that will be running when the client calls the Web service.
For a list of Web services, associated Repository components and items descriptors, see the documentation for
your ATG Web service.
You may find these two optional arguments helpful:
• outputDirectory copies the resultant XML schema to the directory of your choosing.
• mappingFile specifies a file that describes the RepositoryItem properties to include in the resultant XML
schema.
Other Required Schemas
When a client deserializes a RepositoryItem, it uses the schema derived from the item descriptor to
reconstruct each repository object and its properties in the appropriate data types. Depending on the makeup
of the item descriptor, you may need to also generate a schema for related item descriptors.
Consider the Profile repository that uses the user item descriptor. There are two item descriptors, broker
and investor, that are subtypes of user. If you were to use the updateProfile Web service call while
the Relationship Management platform is running, user and all subtypes of it that are part of Relationship
Management are accessible. When you call updateProfile, it’s unclear which version of user you want to call:
user, investor or broker. In this case, you need to generate XML schemes for all three item descriptors.
In short, you need to generate an XML schema for all item descriptors used by RepositoryItems that are
accessed by a Web service call and for any related (parent or child) item descriptors that are running when the
call is made.
It is difficult to supply a general list of all item descriptors for which this added step applies because the contents
of that list depend on many factors. When deciding if you need to create supplemental XML schemas for an item
descriptor, consider the following:
• The Web service you are calling
• The modules running when you call that Web service
• The contents of your ATG module stack
• The custom ATG components you have created that may extend existing components accessed by the Web
service
Note: The previous discussion addresses item descriptors and their subtypes, meaning item descriptors that
inherit from the parent class. This relationship should not be confused with that which item descriptors share
with extensions of themselves, which are added by other modules. For example, the order item descriptor has
one set of properties provided by the Consumer Commerce module. A second order item descriptor is supplied
by Business Commerce and, when both modules are running, the order item descriptors are concatenated so
that Business Commerce properties take precedence. Because all versions of order for the running module are
combined into one, you need only one XML schema for the order item descriptor. When you create that XML
5 Accessing ATG Web Services from Java Clients 51
schema for order, remember to do so while the same modules are running as will run when your Web service
calls that item descriptor.
6 Accessing ATG Web Services from .NET Clients 53
6 Accessing ATG Web Services
from .NET Clients
The ATG platform permits .NET clients to access Nucleus methods by exposing them as ATG Web services. Many
such ATG Web services are included with the ATG platform as are tools for creating custom Web services. For
a list of ATG Web services, see ATG Web Services (page 1). .NET clients are able to contact those Web services
through a carefully constructed call that’s built in .NET, translated into XML wrapped in SOAP, transmitted to
the ATG platform, and routed to the Nucleus method itself. Other ATG resources, such as JMS messages and
RepositoryItems can also be exposed as ATG Web services.
This chapter aims to inform you how to call ATG Web services from a .NET client. Rather than provide a broad
discussion on how to use .NET, this chapter describes ATG-specific features and processes that you need to be
familiar with. Please see your .NET documentation for comprehensive instructions.
To access an ATG Web service, you need to be familiar with the following topics:
About Web Services in the ATG Platform (page 53)
Before You Begin (page 43)
Calling ATG Web Services (page 45)
Using the Atg.DotNet.WebService API to Serialize and Deserialize RepositoryItems (page
58)
About Web Services in the ATG Platform
For the most part, you call ATG Web services in the same way you call Web services elsewhere. While the general
process may not differ, it’s important that you are aware of these platform-specific features.
Security
The content you see as a response to a Web service call depends on your access privileges. When you login
using the loginUser Web service, you provide your user identity. If session sharing is enabled, all subsequent
Web service calls in that session are associated with that identity and related role.
For more information on loginUser, see the ATG Personalization Programming Guide. You may also want to
learn how other Web services handle the security information provided by loginUser. Such information exists
in the ATG Repository Guide and the ATG Commerce Programming Guide.
54 6 Accessing ATG Web Services from .NET Clients
Transactions
When a client calls a Web service, the transactional behavior of the service is managed entirely on the server
side. The method that is exposed as a Web service can use standard transaction demarcation techniques, but
the calling client has no control over this.
There are some practical considerations you should be aware of. If a single Web service call attempts to perform
some operation, and the operation fails, the operation can be rolled back (provided that the Nucleus method
is demarcated properly). However, a transaction cannot span multiple Web service calls so if an operation
is performed by a sequence of Web service calls, and the final call fails, there is no way to roll back the steps
performed by the previous calls.
Session Sharing
When you create a Web service, you specify whether it should be executed within the context of an HTTP
session. Associating Web services with a session enables an application to maintain state across Web service
calls and to use login information for security purposes.
To allow multiple Web services to share a session on .NET, two things need to happen:
1. The Web service client must allow a session to be shared across Web service calls. To do this, you need to
define the Web service calls in the same Web Control and assign a CookieContainer for each call. For
instructions, see Calling ATG Web Services (page 45).
2. The Web services themselves must support sessions. When you create custom Web services, the Web Service
Creation Wizard gives you the option of supporting sessions.
Client Stubs
The ATG platform provides preconfigured client stubs for all ATG Web services in ATGWS.dll. To use these stubs
you need to install ATGWS.dll. See Installing ATGWS.dll (page 55) for instructions. The client stubs provided
here should be sufficient for your ATG Web services. Note that simultaneous calls to a Web service made by
different threads will require that a unique client stub instance exist for each thread.
Web Services that Access RepositoryItems
Standard serializers and deserializers can handle some complex types, such as JMS messages sent to the
ContentViewed and ContentRecommended ATG Web services. When Web services interact with proprietary
technologies, such as RepositoryItems, standard serializers and deserializers don’t understand the source
data type so they aren’t able to recreate it.
A RepositoryItem is a specialized JavaBean called a Dynamic Bean that produces basic get and set methods
for the fields you define for it. Many complex items are stored by the ATG platform as RepositoryItems. The
following Web Services transmit content that’s natively stored as RepositoryItems:
• getProfile
• getRepositoryItem
• performRQLQuery
• getOrderAsXML (Commerce users only)
6 Accessing ATG Web Services from .NET Clients 55
• getOrdersAsXML (Commerce users only)
• getProductXMLById (Commerce users only)
• getProductXMLByDescription (Commerce users only)
• getProductXMLByRQL (Commerce users only)
• getProductSkusXML (Commerce users only)
• getPromotionsAsXML (Commerce users only)
For these Web services, you can use the Atg.DotNet.WebService API to serialize and deserialize related
content. Descriptions for API classes are in Using the Atg.DotNet.WebService API to Serialize and Deserialize
RepositoryItems (page 58). You can find this API in ATGWS.dll, which you need to install in order to access
them. See Installing ATGWS.dll (page 55).
Before You Begin
Before you can access a Web service, you need to make sure the ATG platform is ready for your call and .NET is
configured:
1. Confirm that the application that includes the Web service is deployed on your application server and is
running. For more information, see Deploying Web Services (page 15).
2. Install Internet Information Service (IIS) and then Active Server Page.Net (ASP.NET) and VisualStudio.NET
(VS.NET).
3. Install ATGWS.dll so you can access the stub and API classes it contains. See instructions below.
Installing ATGWS.dll
ATGWS.dll is a library that includes a stub class for each ATG Web service. It also provides the
Atg.DotNet.WebService API used for serializing and deserializing RepositoryItems. All users who want
to access ATG Web services from a .NET client should install ATGWS.dll. You need two versions of ATGWS.dll
on your system. One version lives in you Global Assembly Cache (GAC) so ASP.NET is able to access it when
compiling the Web service call. Another version should exist in a location that VS.NET recognizes.
The instructions provided here direct you to use GACutil, a utility provided by .NET, although you can use any
utility that can install ATGWS.dll to the Assembly folder in your windows directory. While the library does not
need to live on the same machine as .NET, .NET needs to be able to access it.
To install ATGWS.dll:
1. Copy <ATG9dir>/DAS/os_specific_files/i486-unknown-
win32/ATGWS.dll to your Windows\Assembly folder.
2. Open a command prompt and enter the following command:
<DotNetdir>:\ gacutil/i <ATG9dir>/DAS/os_specific_files/i486-unknown-
win32/ATGWS.dll
56 6 Accessing ATG Web Services from .NET Clients
In this example, <DotNetdir> represents the parent directory, such as c:\DotNet that holds your .NET
software.
Keep in mind that each time you install a new version of ATGWS.dll, it coexists with older versions. The latest
version of ATGWS.dll will instruct the .NET client to use it. There’s no need to uninstall ATGWS.dll when you
want to install a new version. Remember when you do install new versions, you need to update references in
VS.NET to the old version of ATGWS.dll. If you’d like to remove all versions of ATGWS.dll, use this command in
a command prompt:
<DotNetdir> gacutil/u <ATG9dir>/DAS/os_specific_files/i486-unknown-win32/ATGWS
Calling ATG Web Services
This section describes the components you need in order to call an ATG Web service. Because there are a few
ways that you can generate a Web service call on .NET, this section focuses only on the ATG resources you will
use and assumes that you will refer to your .NET documentation for specific instructions.
The following sections should provide guidance when creating a Web service call:
Accessing an ATG Web Service (page 56)
Accessing a Custom ATG Web Service (page 56)
Sample Web Service Calls (page 57)
Accessing an ATG Web Service
The ATG platform provides client stubs for all ATG platform Web services in ATGWS.dll. Once you have installed a
version of ATGWS.dll to your GAC and Assembly folders (see Installing ATGWS.dll (page 55) for instructions),
you need to do two things:
1. In your Visual Studio .NET project, make a reference to ATGWS.dll.
2. Create instances of the client stubs and use them in your Web service call.
Accessing a Custom ATG Web Service
To access a Web service that you created in the ATG platform, you create client stub and a reference to it in your
Visual Studio.NET project:
1. Assemble your application. Make sure you include the modules that contain the Web services you want to
access.
2. Deploy the application on your application server and start it up.
3. In your Visual Studio .NET project, add the Web services as Web References.
6 Accessing ATG Web Services from .NET Clients 57
4. When prompted for an Address, provide the WSDL URI, such as:
http://hostname:port/repository/generic/getItem?WSDL
You can find the URI for ATG Web services in the documentation for the specific Web service:
• For Repository Web services, see the ATG Repository Guide.
• For Personalization Web services, see the ATG Personalization Programming Guide.
• For Commerce Web Services, see the ATG Commerce Programming Guide.
Sample Web Service Calls
The Web service call is a document that incorporates calls to any number of ATG Web services that may exist
in the same session. For each Web service, you create an instance of the client stub, call methods on the Web
service, and call the Web service itself. These Web service calls are written in C#.
A Simple Call
This Web service call obtains a RepositoryItem by accessing the getRepositoryItem ATG Web service.
using Atg.DotNet.WebService.Repository.GetRepositoryItem;
// ...
// create stub instance GetRepositoryItemSEIService getItemClientStub = new GetRepositoryItemSEIService(); // assign URL of web service getRepositoryItemClientStub.Url = "http://example.com/repository/generic/getItem/getRepositoryItem"; // call web service string itemXml =getRepositoryItemClientStub.getRepositoryItem("/nucleus/path/to/repository","itemDescriptorName", "repositoryId");
A Complex Call
The following code demonstrates how you would construct a call that uses security controls to restrict the
information users can access. Notice that the loginUser Web service establishes the user identity role, which
other Web services refer to. Because an instance of a CookieContainer is created in this code and assigned to
each Web service stub, all Web services called here exist in the same session.
For brevity these examples omit some details such as a exception handling for the SoapException as well as
class syntax.
using System.Net; // for CookieContainerusing Atg.DotNet.WebService.Repository.GetItem;using Atg.DotNet.WebService.Repository.PerformRQLQuery;using Atg.DotNet.WebService.UserSession.LoginUser;using Atg.DotNet.WebService.UserSession.LogoutUser;
// create stub instancesGetItemSEIService getItemClientStub = new GetItemSEIService();
58 6 Accessing ATG Web Services from .NET Clients
PerformRQLQuerySEIService performRQLQueryClientStub = newPerformRQLQuerySEIService();LoginUserSEIService loginUserClientStub = new LoginUserSEIService();LogoutUserSEIService logoutUserClientStub = new LogoutUserSEIService();
// create a new cookie container for our session and share it between// the various stub instancesCookieContainer cookieContainer = new CookieContainer();getItemClientStub.CookieContainer = cookieContainer;performRQLQueryClientStub.CookieContainer = cookieContainer;loginUserClientStub.CookieContainer = cookieContainer;logoutUserClientStub.CookieContainer = cookieContainer;
// authenticate the user for the sessionloginUserClientStub.loginUser("user", "password", false);
// call servicesstring itemXml = getItemClientStub.getItem("/nucleus/path/to/repository", "itemDescriptorName", "repositoryId");string[] itemsXml = performRQLQueryClientStub.performRQLQuery("/nucleus/path/to/repository", "itemDescriptorName", "property = 'value'");
// log out the userlogoutUserClientStub.logoutUser();
Using the Atg.DotNet.WebService API to Serialize and
Deserialize RepositoryItems
The Atg.DotNet.WebService API is a mechanism that you can use to serialize and deserialize
RepositoryItem content. The primary role of this API is to:
• Converts a RepositoryItem into an XML document (serialization).
• Formats an XML document into a RespositoryItem (deserialization).
By understanding the ATG RepositoryItem API, Atg.DotNetWebService.RepositoryItem is able to
convert into objects any content that uses the RepositoryItem API for its underlying data type. You can use
this API for ATG and custom Web services that access RepositoryItems.
The Atg.DotNet.WebService is made up of the following classes:
• RepositoryItem Class (page 60)
• Property Class (page 61)
• RepositoryItemRef Class (page 61)
• Complex Type Class (page 62)
• NoSuchPropertyException Class (page 62)
6 Accessing ATG Web Services from .NET Clients 59
• RepositoryItemSerializer Class (page 62)
• RepositoryItemSerializationException Class (page 63)
Note: Rather than use this API, you could generate an XML schema representation of the RepositoryItem
and use that serialize/deserialize content. The advantage of using an XML schema is that you can control the
properties you use, meaning you can easily exclude certain properties from your schema. You may find the
disadvantages, namely the limitations in property types and values that this method supports, reason to use
the provided API instead. For instructions on how to use an XML schema for serialization/deserialization, see the
Creating a Serializer and Deserializer (page 48) in the Java client chapter.
About the Atg.DotNet.WebService API
Collectively, these classes provide you with the ability to serialize and deserialize RepositoryItems and to
configure both processes. Although this discussion specifically describes the serialization process, the same
principles apply to both processes.
When you want to deserialize content from a Web service, for example, you use the response sent by ATG Web
service resulting from your initial Web service call. The response, formatted in XML, holds a string object that
represents ATG RepositoryItems. Once you make the call to the API to deserialize the string, the deserializer
parses the string into a RepositoryItem object.
Not all content in the string is emitted by the serializer. By default, only content specified as “dirty,” meaning a
different value for it exists in the ATG platform and the external system .NET communicates with, is serialized.
Once an item has been serialized, there’s parity across systems so all properties on that item are marked as
“clean.” You can alter the default dirty/clean designation in the following ways:
• Use the RepositoryItem.Dirty property to toggle an object’s clean/dirty status.
• Use the RepositoryItem.setPropertyDirty() methods to toggle a property’s clean/dirty status.
During deserialization, content that represents RepositoryItem properties is parsed based on a few rules. All
properties are converted back to the native data type, assuming that data type is available in .NET. The following
data types don’t exist in .NET and so values for these types are converted as follows:
• ATG Map properties use Hashtable data type in .NET.
• ATG Date or Timestamp properties are stored as .NET DateTime data type.
• ATG Set properties are formatted as .NET Array data type.
• ATG properties that refer to other ATG RepositoryItems behave as .NET Hashtables.
For the most part, Atg.DotNet.WebService determines format output type by relying on prior processing.
For example, if it had deserialized a particular RepositoryItem, such a Growth fund, then assuming no new
properties are added, when the Growth fund is serialized, Atg.DotNet.WebService.RepositoryItem is
aware of each property’s destination data type. However, in all other circumstances, you should explicitly include
the XML data type for the property. In short, under these circumstances include data types:
• The first time a RepositoryItem is serialized when it hasn’t been previously deserialized, such as in the case
of adding a new item to the ATG platform.
• A new property value is assigned to an empty RepositoryItem.
Note: In order to use the classes in this interface, make sure that the ATG platform atg/repository/xml/
RepositoryXMLTools component has the encodeRepositoryIdAsAttr property set to true. This is the
default setting.
60 6 Accessing ATG Web Services from .NET Clients
RepositoryItem Class
The Atg.DotNet.WebService.RepositoryItem class is designed to manage XML serialization and
deserialization for easy interoperability with the .NET Web services framework.
To serialize or deserialize a RepositoryItem, you need only to pass in the RepositoryName and
RepositoryId. When you are working with content for the first time, you also need to call setPropertyType
to instruct the deserializer/serializer to use a specific output data type.
Properties
Dirty
Determines the overall dirtiness of an object by specifying whether all properties are clean (false) or one of
more properties are dirty (true).
ItemDescriptorName
Name of the item descriptor associated with the object’s RepositoryItem.
Properties
List of properties for this RepositoryItem.
RepositoryId
ID provided to the object’s RepositoryItem representation.
RepositoryName
Name of the repository that the RepositoryItem is part of.
Constructors
RepositoryItem()
Constructs a new, empty RepositoryItem object. When you serialize or deserialize a property with a
value that is a pointer to a RepositoryItem, be sure to supply it a RepositoryName, RepositoryId, and
ItemDescriptorName when you invoke the setRepositoryItem method.
RepositoryItem(string)
Constructs a new RepositoryItem in the ATG platform, populating it with values parsed from the XML instance
of the Web service call. The XML instance is a by-product from the Web service call generation.
Methods
clearPropertyValues
Clears all property values for a given RepositoryItem. Before using
RepositoryItemSerializer.deserialize, it’s a good idea to use this method to clear all previous values.
isPropertyDirty
Determines whether a given property value is dirty (true) or clean (false).
setPropertyDirty
Designates a given property as dirty.
getPropertyValue
Returns the value provided for a property in the ATG platform. If the property does not exist in the ATG platform,
an error of type ATGWS.NoSuchPropertyException is thrown.
setPropertyValue
Sets a value for a property in the ATG platform.
getPropertyType
6 Accessing ATG Web Services from .NET Clients 61
Returns the property’s XML data type.
setPropertyType
Specifies the XML data type for the property value.
serialize
Creates a string representation of an XML document for the RepositoryItem.
Property Class
This class represents a given property’s name and value.
Properties
Dirty
Determines whether a given property is dirty (true) or clean (false). If you indicate that a property value
should change by invoking the RepsoitoryItemsetPropertyValue call, this property is set to true. Once a
response is returned from the setPropertyValue call, this property is set to false.
XmlType
XML data type that will be used to represent the property’s value.
Constructor
Property()
Constructs an empty object representing a property.
Methods
getName
Returns the name of the property.
getValue
Returns the value of the property.
setValue
Sets a new value to the property.
RepositoryItemRef Class
This class represents a reference to another RepositoryItem.
Properties
RepositoryName
Name of the repository of which the referenced RepositoryItem is a part.
ItemDescriptorName
Name of the item descriptor used by the referenced RepositoryItem .
RepositoryId
ID for the referenced RepositoryItem .
Method
setRepositoryItem
62 6 Accessing ATG Web Services from .NET Clients
Initializes the ItemRef to refer to the provided RepositoryItem.
Complex Type Class
This class permits you to serialize/deserialize properties that use complex types by specifying an output data
type explicitly.
Properties
TypeName
Data type for the RepositoryItem property.
Properties
Name of any properties that are either deserialized from or serialized into the complex type.
Constructor
ComplexType()
Constructs an empty object to represent all properties of a complex data type.
Methods
getPropertyValue
Retrieves values from the ATG platform for the specified properties. If the property does not exist in the ATG
platform, an error of type ATGWS.NoSuchPropertyException is thrown.
setPropertyValue
Sets a property to a value supplied as an input.
getPropertyType
Returns the XML data type for the property value.
setPropertyType
Specifies the XML data type for the property value.
NoSuchPropertyException Class
This class generates an exception each time a getProperty or getPropertyValue method tries to interact
with a property that has not been specified for the designated RepositoryItem.
Properties
PropertyName
Name of the property that you are trying to work with.
Constructor
NoSuchPropertyException
Constructs the exception.
RepositoryItemSerializer Class
This class conducts serialization/deserialization and permits you to decide if you want all or only dirty properties
to be updated.
6 Accessing ATG Web Services from .NET Clients 63
Constructors
RepositoryItemSerializer()
Constructs a serializer instance.
RepositoryItemSerializer(RepositoryItem)
Constructs an object holding serialized content.
Methods
deserialize (string)
Deserializes an XML-formatted string into a new RepositoryItem.
deserialize (string, boolean)
Deserializes an XML document string into a RepositoryItem. Additional arguments true or false indicate
whether values for only dirty properties (true) or all properties (false) should be deserialized.
serialize (string)
Serializes a RepositoryItem into an XML-formatted string document.
serialize (boolean)
Serializes a RepositoryIteminto an XML document. Additional arguments true and false indicate whether
values for only dirty properties (true) or all properties (false) should be deserialized.
RepositoryItemSerializationException Class
This class creates an exception object when errors occur during serialization or deserialization.
Constructor
RepositoryItemSerializationException()
Constructs an empty exception object.
Part II. Integration Framework
In addition to the ATG Web services functionality discussed in the preceding chapters, the ATG platform includes a more
generalized framework that enables you to integrate your applications with remote software systems for cases where
using Web services might not be appropriate. For example, you could use the integration framework to integrate an ATG
Commerce application with an order-processing system. When a customer places an order through ATG Commerce, the order
data can be transferred to the order-processing system, and the ATG platform can trigger events that invoke the processing
facilities in the remote system.
The integration framework involves several key facilities that you can use to integrate ATG applications with remote systems:
• JMS messaging, configured through Patch Bay, to enable the ATG platform to trigger events in the remote system, or the
remote system to trigger events in the ATG platform. See the Dynamo Message System chapter of the ATG Programming
Guide.
• Remote Procedure Calls (page 93) (RPC), for interapplication command execution. For example, the ATG platform can use
RPC to query an inventory management system.
• Data integration, using the Repository to XML Data Binding (page 27) facility (described in Part I of this guide) and the
Integration Repository (page 67).
You can use these facilities individually, but a typical integration will use all of these facilities together. For example, the
Integration Repository typically uses RPC to execute the commands used to move data between the ATG platform and the
remote system.
Integrators and Adapters
Integrating the ATG platform with a remote system generally involves additional software to handle the communication
between the two systems:
• A middleware transport layer, such as Tibco or MQ
• Adapters that enable the ATG platform and the remote system to communicate through the middleware transport layer
• An integrator that implements the Integration Framework’s queries and commands in a form understood by the remote
system, enabling the two systems to interoperate and share data
The following figure illustrates the ATG integration architecture:
You can write adapters and integrators by implementing the various APIs described in this manual. Note that ATG adapters
handle only the communication between the ATG platform and the middleware transport. Adapters for communication
between a remote system and a middleware transport are typically available from the company that develops the remote
system or the middleware.
7 Integration Repository 67
7 Integration Repository
The ATG Integration Framework includes the Integration Repository, which adds to ATG’s Repository feature
the ability to represent data on external systems as ATG repository items. The Integration Repository provides
several key features for integrating ATG with external systems:
• You can execute queries from ATG against remote systems. The Integration Repository represents the results
of the queries as repository items.
• You can create queries using RQL or other ATG query building techniques, and the Integration Repository
translates the queries into the format required by the remote system.
• When data from the remote system is represented as repository items, the Integration Repository can
automatically submit changes to these items to the remote system without requiring special update calls to a
remote system.
Architecture
The Integration Repository is a wrapper around an ATG SQL repository, which is referred to as the local
repository. In a system architecture that uses an Integration Repository, the integrated data resides in the remote
system, rather than just in a local database, and queries are made using the RPC command structure described
in the Remote Procedure Calls (page 93) chapter.
Just like other repositories, an Integration Repository defines one or more item descriptors. Each item descriptor
defines one or more commands to be used for the operations that need to interact with the remote system:
• executeQuery
• getItem
• createItem
• updateItem
• removeItem
These operations are described in more detail in the Command Operations (page 77) section of this chapter.
Each command involves an RPC call that may access the remote system, as described in the Remote Procedure
Calls (page 93) chapter.
The Integration Repository enables you to use ATG’s Repository Query Language (RQL) and all the RQL droplets
to access data that is stored on remote systems. The translation between RQL and the query format required by
68 7 Integration Repository
the remote system is handled by an implementation of the IntegrationRepositoryView (page 76) class. An
implementation of IntegrationRepositoryView typically needs to be written for each remote system you
want to integrate with ATG.
Wrapping the SQL repository provides the Integration Repository with superior performance and robustness
by leveraging the SQL repository’s sophisticated item caching features. You can persist data from the remote
system locally in a SQL repository. By maintaining locally-cached copies of the remote data, the Integration
Repository can make the data available more quickly than if you needed to access the remote system every time
you needed to access the data. In addition, the local SQL repository offers a degree of protection against the
remote system being temporarily unavailable.
More details of the Integration Repository architecture are described in the Integration Repository APIs (page
71) section of this chapter.
Integration Approaches
The Integration Repository is designed to help integrate ATG applications with remote systems. It assumes
that your business maintains data on a remote system and you want to expose and possibly modify this data
within your ATG application in the form of ATG repository items. There are several ways you can set up such an
integration, depending on the demands of your ATG application and the characteristics of the remote system
and the data maintained there. Here are four possible approaches for getting remote data. Which approach to
choose depends on balancing your need for consistent data and best performance.
Remote Only
In this case, the data is maintained only on the remote system. Each time that the ATG application needs to
access the data, a command is issued to the remote system. The local repository is configured to use transient
repository items.
Advantages:
• You are always sure that the data returned to ATG is up to date.
Disadvantages:
• If the remote system is unavailable, then no form of the data is available to the ATG application.
• Frequent queries to the remote system can affect the performance of the remote system, which may also be
serving functions other than the ATG application.
• The need to query the remote system will tend to slow the performance of the ATG application.
See Configuring the Remote-Only Model (page 82) for more details about how this approach could be
configured.
Remote then Local
In this case, the primary source for the data is the remote system. Each time that the ATG application needs to
access the data, a command is issued to the remote system. If the command fails to return, then the command is
issued to the local repository.
7 Integration Repository 69
Advantages:
• You are sure that the data returned to ATG is up to date, except in cases where the remote system is
unavailable. In addition, the existence of the local repository can provide a backup form of the data, in case
the remote system is inaccessible.
Disadvantages:
• Frequent queries to the remote system can affect the performance of the remote system, which may also be
serving functions other than the ATG application.
• The need to query the remote system will tend to slow the performance of the ATG application.
See Configuring the Remote-then-Local Model (page 83) for more details about how this approach could be
configured.
Local then Remote
In this case, a version of the data is maintained in a local repository. Only if the data is not available locally, or if
the local copy has been marked invalid or has expired, does the Integration Repository query the remote system
for the data.
You might use this integration model if you need to make sure the system is as fast as possible, and you don’t
have to worry so much about data consistency because the data does not change that often. When the remote
system is down, you can block changes to the data (updates, creating and removing items), but you make the
data available from the local system, so that your users can continue to work.
Advantages:
• ATG’s performance is as fast as possible.
• There are fewer queries to the remote system, so less burden is placed on the remote system.
• You can configure the lifetime of items in the local repository, so you can be assured that the data is not out of
date by more than a specified amount of time.
Disadvantages:
• You have less assurance that the data returned from the local repository is consistent with the data in the
remote system.
See Configuring the Local-then-Remote Model (page 84) for more details about how this approach could be
configured.
Local Only
This approach doesn’t need to use the ATG Integration Framework. In this case, we periodically dump data from
the remote system into the relational database used by the ATG application. The data is accessed by the SQL
repository. Since this approach doesn’t need to issue commands against the remote system in real time, there
doesn’t need to be an Integration Repository.
Advantages:
• ATG’s performance is as fast as possible.
70 7 Integration Repository
• The only interaction with the remote system is a periodic batch data transfer, which probably can be
scheduled to place a minimal burden on the remote system.
Disadvantages:
• The local repository is not updated in real time, so any changes in the remote system are reflected in the local
repository and therefore in your Web application only after the scheduled data transfer.
Setting Up an Integration Repository
Here is a brief overview of the steps involved in setting up an Integration Repository:
1. Create and configure an Integration Repository. This is a component of class
atg.adapter.integrations.IntegrationRepository. Configure the properties described in the
Integration Repository (page 67) section.
2. Create the Integration Repository’s definition file, as described in the Defining an Integration
Repository (page 70) section.
3. Create and configure your local repository. The local repository is a normal SQL repository. See SQL Repository
Overview in the ATG Repository Guide for more information.
4. Create the database schema for your local repository.
5. Create any mapping files you desire for each item descriptor in the Integration Repository. See
Mapping (page 80) for more information.
6. Create a subclass of IntegrationRepositoryView for each remote system you need to query.
7. Create Commands that correspond to each of the command operations you want to define for your
Integration Repository. See the Remote Procedure Calls (page 93) chapter.
To set up a complete integration with a remote system, you will also need to perform many tasks that are
outside the scope of this chapter. You will need to configure the transport layer that connects ATG to the remote
system. You will also typically want to create a portlet (ATG Portal gear) or set of form pages to display and
modify data from the remote system.
Defining an Integration Repository
The Integration Repository is defined by an XML template file. This file is specified by the definitionFile
property of the IntegrationRepository component. The Integration Repository definition file defines
the integration behavior, including the commands used for the executeQuery, getItem, createItem,
updateItem, and removeItem integration operations. The elements of the Integration Repository definition file
are described in the Integration Repository Definition File (page 85) section. The commands are described in
the Command Operations (page 77) section.
Since the Integration Repository wraps another repository, the underlying SQL repository also requires a
definition file to define the repository item properties. You may also want to create mapping files to handle the
relation of your repository item properties to the data maintained on the remote system. See the Repository to
XML Data Binding (page 27) chapter for more information.
7 Integration Repository 71
This is an example of what the Integration Repository definition file would look like. It defines a single item
descriptor, named account, and specifies the Commands used to query, get, add, update, and remove account
items:
<integration-repository-template> <header> <name>RemoteX Repository</name> </header>
<item-descriptor name="account"> <query command="/atg/integrations/remotex/queries/AccountQuery" view="atg.integrations.remotex.RemoteXView"> </query> <get-item command="/atg/integrations/remotex/queries/AccountQuery"> </get-item>
<add-item command="/atg/integrations/remotex/queries/AccountUpdateRPC"> </add-item> <update-item command="/atg/integrations/remotex/queries/AccountUpdateRPC"> </update-item> <remove-item command="/atg/integrations/remotex/queries/AccountDeleteRPC"> </remove-item>
</item-descriptor></integration-repository-template>
The Integration Repository definition file conforms to a DTD file at this URL:
http://www.atg.com/dtds/integrations/integration-repository_1.0.dtd
The Integration Repository is also configured using normal JavaBean properties. An IntegrationRepository
component might be configured in a properties file like this:
$class=atg.adapter.integrations.IntegrationRepository
repositoryName=MyStufflocalRepository=/mystuff/MyLocalRepositorydefinitionFile=/mystuff/irConfig.xmltransactionManager=/atg/dynamo/transaction/TransactionManagerintegrationRepositoryTools=/atg/integrations/repository/IntegrationRepositoryToolspersistentCacheManager=/atg/integrations/repository/PersistentCacheManagermappingManager=/atg/repository/xml/SchemaManagermappingTools=/atg/integrations/repository/MappingToolslockManager=/atg/dynamo/service/ClientLockManager
The Integration Repository (page 67) section describes these properties.
Integration Repository APIs
The Integration Repository consists of a set of item descriptors. Each item is queryable through a
RepositoryView using a QueryBuilder. Each item descriptor is associated with a particular Command or set
72 7 Integration Repository
of Commands. One of these Commands returns results that are converted to repository items of the given item
descriptor. Other Commands are used for updating or deleting values in the remote system.
The Integration Repository includes extensions to, or implementations of, the following repository classes. Each
of these classes is in the atg.adapter.integrations package.
Integration Repository (page 67) extends atg.repository.RepositoryImpl
IntegrationRepositoryItemDescriptor (page 75) extendsatg.repository.ItemDescriptorImpl
IntegrationRepositoryItem (page 75) implements atg.repository.RepositoryItem,atg.repository.MutableRepositoryItem
ChangedPropertyBean (page 75) implements atg.repository.RepositoryItem,atg.repository.MutableRepositoryItem
atg.repository.databinding.MappingRepositoryItem (page 75) implementsatg.repository.RepositoryItem, atg.repository.MutableRepositoryItem
IntegrationRepositoryView (page 76) extends atg.repository.RepositoryViewImpl
In addition, each IntegrationRepositoryItemDescriptor refers to one or more commands, which
implement the atg.integrations.Command interface. The RPC call in a Command returns an object of the
atg.integrations.CommandResult class. Command and CommandResult are discussed in the Remote
Procedure Calls (page 93) chapter.
IntegrationRepository
extends RepositoryImpl
The IntegrationRepository references another repository, which is referred to as the local repository and
which is a SQL repository. The IntegrationRepository is defined by a Nucleus properties file and an XML
definition file. Each method call functions as described in the Methods (page 60) section, forwarding the request
either to the local repository or to the IntegrationRepositoryItemDescriptor, which then executes a
Command against the remote system.
Properties
localRepository
The SQL repository that acts as a local repository. The local repository is a normal SQL repository. It might be
configured in a properties file like this:
//mystuff/MyLocalRepository.properties
7 Integration Repository 73
$class=atg.adapter.gsa.GSARepository
definitionFiles=/mystuff/localConfig.xmlrepositoryName=MyLocalStuffgroupContainerPath=/atg/registry/RepositoryGroupsXMLToolsFactory=/atg/dynamo/service/xml/XMLToolsFactorytransactionManager=/atg/dynamo/transaction/TransactionManagerdataSource=/atg/dynamo/service/jdbc/JTDataSourceidGenerator=/atg/dynamo/service/IdGenerator
definitionFile
The Integration Repository definition file. This is an XML file that uses the Integration Repository DTD, http://
www.atg.com/dtds/integrations/integration-repository_1.0.dtd . See Integration Repository Definition File (page
85) for information about creating an Integration Repository definition file
integrationRepositoryTools
This is a property of type atg.adapter.integrations.IntegrationRepositoryTools. This class
provides a set of helper methods that are used to convert between the local repository items and the
remote system’s data format. An instance of this class exists at /atg/integrations/repository/
IntegrationRepositoryTools.
persistentCacheManager
This is a property of type atg.adapter.integrations.PersistentCacheManager. This class provides
management of persistent caching. An instance of this class exists at /atg/integrations/repository/
PersistentCacheManager. See the Persistent Caching (page 80) section.
mappingManager
This is a property of type atg.repository.databinding.MappingManager. You can optionally define a
mapping of the local repository item to the data on the remote system. This class manages that mapping. See
Mapping (page 80) in this chapter and see also the Repository to XML Data Binding (page 27) chapter.
mappingTools
This is a property of type atg.repository.databinding.MappingTools, which is a helper class to manage
the mappings. An instance of this class exists at /atg/integrations/repository/MappingTools.
defaultTimeoutResponse
The Integration Repository needs to deal with the case of a Command timing out before a result is returned from
the remote system. If the Command times out, this property defines what the default behavior should be. There
are four choices:
ROLLBACK Rollback the current transaction.
INVALID Mark the item’s state as invalid. See Persistent Caching (page 80).
UNKNOWN Mark the item’s state as unknown. See Persistent Caching (page 80).
IGNORE Do nothing.
sendScenarioEvents
A boolean property that controls whether the repository sends scenario events. The Integration Framework
includes one scenario event by default, atg.adapter.integrations.IntegrationExternalIdChange,
74 7 Integration Repository
which is sent when the externalId of an item is set. To trigger this event, use the
IntegrationRepositoryTools.externalIDWasUpdated method.
Methods
Most methods in the IntegrationRepository class are pass-throughs to the local repository. The following
methods provide special behavior:
getItem
Depending on how you have configured the Integration Repository, this method either:
• calls localRepository.getItem and, if the result is null, then calls
IntegrationRepositoryItemDescriptor.getRemoteItem, or
• calls IntegrationRepositoryItemDescriptor.getRemoteItem and, if the result is null, then calls
localRepository.getItem, or
• calls IntegrationRepositoryItemDescriptor.getRemoteItem only.
Both the local repository’s query cache and the IntegrationRepository’s query cache will be used
depending on the item descriptor. If the IntegrationRepository definition file includes a query Command,
then the IntegrationRepository executes the query (and uses its query cache). If there is no query Command,
then the query is forwarded to the local repository.
For a more detailed description, see getItem (page 78) in the Command Operations (page 77) section.
getView
This method can operate in two ways. If querying is implemented in the local repository (no query command)
then this returns a LocalRepositoryViewWrapper. If a Command is used for querying then this returns the
configured RepositoryView class.
getItemDescriptor
Return an IntegrationRepositoryItemDescriptor (page 75) that wraps an item descriptor from the local
repository. The local repository’s item cache will be used.
getItemForUpdate
getItemsForUpdate
Return one (or more) IntegrationRepositoryItem, using similar behavior to the getItem method above.
createItem
Call localRepository.createItem. This method is just a pass through. See addItem.
addItem
Call localRepository.addItem. Also call IntegrationRepositoryItemDescriptor.addRemoteItem. For
a more detailed description, see addItem (page 25) in the Command Operations (page 77) section.
updateItem
Call localRepository.updateItem. Also call
IntegrationRepositoryItemDescriptor.updateRemoteItem. For a more detailed description, see
updateItem (page 25) in the Command Operations (page 77) section.
removeItem
Call localRepository.removeItem. Also call
IntegrationRepositoryItemDescriptor.removeRemoteItem. For a more detailed description, see
removeItem (page 25) in the Command Operations (page 77) section.
Each of the Command executions is relevant only if the given command is defined for the item descriptor.
7 Integration Repository 75
IntegrationRepositoryItemDescriptor
extends ItemDescriptorImpl
This class references an item descriptor from the local repository. Most operations will be pass-throughs to the
local repository item descriptor. The following operations (described in the Command Operations (page 77)
section) execute a Command if one is defined for the item descriptor; otherwise they do nothing.
executeQuerygetItemupdateItemaddItemremoveItem
In addition, this class is responsible for converting the results of queries obtained from the remote system into
repository items.
IntegrationRepositoryItem
implements RepositoryItem, MutableRepositoryItem
This class references a repository item in the local repository. Most operations will be pass-throughs to it.
ChangedPropertyBean
implements RepositoryItem, MutableRepositoryItem
This class includes only the external ID property plus the list of properties in a RepositoryItem that have been
changed. When, for example, updateItem is invoked on an IntegrationRepositoryItem, this wrapper can
be passed to the update Command instead of the RepositoryItem. This allows us to send only the changed
properties to be saved to the remote system, instead of trying to update all the properties of a repository item.
For example, if you change the middleName property of the user profile, and the user profile is configured
with an external id property called remoteId, the ChangedPropertyBean will only expose two properties:
middleName and remoteId. If you call ChangedPropertyBean.getPropertyDescriptors, the result will
only contain these two properties. A ChangedPropertyBean is read-only.
atg.repository.databinding.MappingRepositoryItem
implements RepositoryItem, MutableRepositoryItem
A MappingRepositoryItem wraps a repository item and exposes properties as they are configured in a
mapping file. The Integration Repository creates MappingRepositoryItems automatically if it is configured
with a mapping file. The property names that are exposed are the target names as defined in the mapping file.
If a property’s include attribute is false in the mapping file, then that property is not a legal property of the
MappingRepositoryItem. For example, if the following mapping exists:
<item-descriptor repository-path="/atg/userprofiling/ProfileAdapterRepository" name="user"
76 7 Integration Repository
default-include="false"> <property name="firstName" include="true"/> <property name="lastName" include="true"/> <property name="id" target-name="dynamoId" include="true"/></item-descriptor>
then the corresponding MappingRepositoryItem would contain three properties: firstName, lastName, and
dynamoId.
See the Repository to XML Data Binding (page 27) chapter.
IntegrationRepositoryView
extends RepositoryViewImpl
IntegrationRepositoryView is an abstract class that provides some standard operations like applyOptions
and getRange. For each type of remote system that you want to integrate with, you need to create an
implementation of IntegrationRepositoryView specific for your remote system in order to provide the
translation between the ATG Query format, and the format expected by the remote system. When a query is
executed, the executeUncachedQuery method is called. That method looks like this:
public RepositoryItem[] executeUncachedQuery(Query pQuery, QueryOptions pOptions){ // Step 1 Object input = createQueryCommandInput(pQuery, pOptions);
// Step 2 RepositoryItem[] items = executeQueryCommand(input);
// Step 3 return applyOptions(items, pOptions);}
The inputs to this method are a standard Query object and a standard QueryOptions object. The
executeUncachedQuery method goes through the following steps:
Step 1
The first thing the view needs to do is translate the Query object into an object that is understandable by the
remote system. This is the responsibility of your subclass of IntegrationRepositoryView and the only
method that you must implement.
Step 2
This step is a call to the method defined in IntegrationRepositoryView that gets the correct Command
according to your configuration and calls Command.execute with the provided query input.
Step 3
This step may not be necessary. If your remote system supports sorting and ranging (returning a subset of the
items) then it will be more efficient for that information to be included in the command input. In that case this
step can be skipped in the executeUncachedQuery and you should override the applyOptions method to do
nothing.
The only thing required for querying to work is to subclass IntegrationRepositoryView and implement
createQueryCommandInput. The implementation of this method will introspect the Query class and create an
7 Integration Repository 77
input object. The type and contents of the input object depend on the requirements of your application and the
remote system you are querying. You then need to create a Command that knows what to do with this input.
In addition, you will typically need to implement a processResults method in your
IntegrationRepositoryView subclass. This method is responsible for translating between the remote data
format and the repository items in the local repository.
The default implementation of IntegrationRepositoryView.processResults calls
IntegrationRepositoryTools.createRepositoryItems. It passes in the results from
pCommandResult.getResults() as the first argument. The createRepositoryItems method
uses DynamicBeans to look at the given command results. For each object in the result it uses the
IntegrationRepositoryItemDescriptor to find the external ID. It uses this external ID to look for an
existing item in the local repository with the same external ID. If one is found, this method iterates across the
properties in the result object (using DynamicBeans) and updates the properties. If one is not found, a new item
is first created, then the properties are updated.
Command Operations
The Integration Repository can define five types of operations that allow ATG repository items to access data in
remote systems:
• executeQuery (page 77)
• getItem (page 78)
• addItem (page 25)
• updateItem (page 25)
• removeItem (page 25)
executeQuery
There are four possibilities here:
• Always query against the local repository. For example, you may decide that updates to profiles need to be
sent to a remote system, but queries of that data will always be done locally.
• Always query against the remote system. For example, you may want the data to remain in the remote system
with no persistent storage in Dynamo.
• Check the local repository first, then check the remote system.
• Check the remote system first, then Dynamo.
If there is a Command associated with the query operation then the remote system is queried. If no Command is
configured, then the local repository is queried.
When you want to execute a query against the Integration Repository, your code will look something like this:
Repository rep = getRepository(getMyRepository());
78 7 Integration Repository
RepositoryView view = rep.getView(getMyView());QueryBuilder builder = view.getQueryBuilder();Query query = builder.createSomeQuery(MyQueryExpression);RepositoryItem[] results = view.executeQuery(query);
There is no Integration Repository specific code in any of this. This is because you build queries with the
Integration Repository in exactly the same way that you would build queries with the SQL repository. This also
means that you can use RQL. You can use standard query builder calls, so the Query object that gets generated
is a standard Query object from the atg.repository.query package.
This real difference is in the RepositoryView. The Integration Framework uses a subclass named
IntegrationRepositoryView. This class provides an implementation of executeUncachedQuery that is
expected to call the queryCommand. There needs to be a subclass of IntegrationRepositoryView for each
remote system you want to query. This subclass is responsible for translating between the ATG Query and the
query format expected by the remote system.
A queryCommand will receive whatever input is created by the createQueryCommandInput method of your
IntegrationRepositoryView.
The IntegrationRepositoryView.processResults method is responsible for translating between the
remote data format and our repository items.
getItem
The getItem operation returns the value from the local repository. If there is no result, or if the entry in the
local repository is invalid, the getItem operation updates the local repository with the results returned by the
execution on the remote system of the Command associated with the getItem operation.
This operation uses the IntegrationRepositoryItemDescriptor.getRemoteItem()
method. Commands executed for get-item will receive whatever input is created by
IntegrationRepositoryTools.createGetCommandInput(). By default this is a map of the external
ID property name to the value of the external ID. If you require a more complex command input, extend
IntegrationRepositoryTools and override the createGetCommandInput() method.
If the item descriptor’s use-external-id attribute is true, then the given local repository item ID is identical
to the remote ID. If this attribute is false, then the remote ID must be retrieved from the local item (using the
item descriptor’s external-id-property).
If getRemoteItem throws an exception, then if the item descriptor’s use-local-on-failure attribute is true,
the operation returns the value from the local repository. Otherwise, the exception is passed on.
updateItem
The updateItem operation updates the values of the repository item’s properties both in the local repository
and the remote system. The update is handled transactionally, so that if the update of the remote system fails,
the change to the local value will not occur.
This operation uses the IntegrationRepositoryItemDescriptor.updateRemoteItem() method.
If the Integration Repository item descriptor defines a mapping file for the updateItem operation, then
the updateItem operation creates a MappingRepositoryItem. If the changed-properties-only
attribute is true, then the updateItem operation creates a ChangedPropertyBean. Otherwise, the
IntegrationRepositoryItem is used.
7 Integration Repository 79
The input for the updateItemCommand is either the IntegrationRepositoryItem, the
MappingRepositoryItem, or the ChangedPropertyBean as appropriate. It returns a CommandResult.
The updateItem operation checks if there is an external ID in the CommandResult returned by the
updateItemCommand. If there is, the updateItem operation updates the external ID property of the local
repository item with the value.
If update-local-with-result is set to true, then the Integration Repository looks in the CommandResult for
new property values. Any values that appear in the result will be set on the local value of the item.
If the updateRemoteItem call times out, the response depends on the setting of the timeout-response
attribute for the updateItem operation. The possible settings are ROLLBACK, INVALID, UNKNOWN, IGNORE.
updateItem and Derived Properties
If your underlying local repository uses the derived properties feature of the SQL repository and you are using
the changed-properties-only attribute set to true, then you should define a derived-properties
element to specify how the derived properties are handled. The derived-properties element is a container
for a list of derived properties mapped to some property that is used in the derivation. It ensures that if the
value of a property that is one of the derivation expressions of a derived property is changed, the Integration
Repository treats the derived property itself as changed as well.
The derived-properties element can optionally be used as a child element of an update-item Tag (page
87). It is a container for one or more property elements, each of which has a name attribute and a
referenced-property attribute. The name attribute is the name of a property that can be derived from the
referenced-property. The name attribute and referenced-property attribute must both be valid property
names defined within the given item descriptor.
If changed-properties-only="true" in the update-item element, then whenever the referenced-
property is sent in the update command, the name property will be as well. For example, suppose you have a
property named remoteAddress that can be derived from a property named businessAddress. By including
this derived-properties element in the update-item element, then whenever the businessAddress
property is included as a changed property, the remoteAddress property will also be included as a changed
property:
<derived-properties> <property name="remoteAddress" referenced-property="businessAddress"/></derived-properties>
If you do not configure the derived-properties element for any derived properties in your item, then a
change to a derived property’s expression will not cause the derived property itself to appear as a changed
property. See SQL Repository Data Models: Derived Properties in the ATG Repository Guide for more information
about derived properties.
addItem
The addItem operation adds the item to the local repository and to the remote system. If the addItem
operation fails on the remote system, then the item will not be added to the local system. Since the item is being
newly added to the remote system, it is impossible to know in advance what value of the external ID is. The
addItem operation attempts to set the external ID property with the result of the addItemCommand. If the use-
external-id attribute is true, then a change to the ID results in a clone of the item passed into this operation.
This operation uses the IntegrationRepositoryItemDescriptor.addRemoteItem() method. The input
for add-item Commands is the RepositoryItem being added. If the Integration Repository item descriptor
80 7 Integration Repository
defines a mapping file, then the addItem operation creates a MappingRepositoryItem. Otherwise, the
IntegrationRepositoryItem is used.
When the addItemCommand returns successfully from the remote system, the addItem operation checks if there
is an external ID in the CommandResult. If there is, the addItem operation updates the external ID property
in the local repository with the ID value. If update-local-with-result is set to true, then the Integration
Repository looks in the CommandResult for new property values. Any values that appear in the result will be set
on the local value of the item. If the item was cloned, the original item is removed and the new item is returned.
If the addRemoteItem call times out, the response depends on the setting of the timeout-response attribute
for the addItem operation. The possible settings are ROLLBACK, INVALID, UNKNOWN, IGNORE.
removeItem
The removeItem operation removes the item from the local repository and from the remote system. This
operation uses the IntegrationRepositoryItemDescriptor.removeRemoteItem() method. If there
is a mapping file defined in the item descriptor, the target name of the external ID property is used. If the
useExternalId is false, then the given ID is the local repository item ID.
The input for commands executed for remove-item is whatever input is created by
IntegrationRepositoryTools.createRemoveCommandInput(). By default this is a map of the external
ID property name to the value of the external ID. If you require a more complex command input, extend
IntegrationRepositoryTools and override the createRemoveCommandInput() method.
If the remove operation in the remote system fails, the local item will not be removed. If the removeRemoteItem
call times out, the response depends on the setting of the timeout-response attribute for the removeItem
operation. The possible settings are ROLLBACK, INVALID, UNKNOWN, IGNORE.
Mapping
The ATG Integration Framework provides tools to help you map ATG repository items to data objects on the
remote system. Rather than export all the properties of a repository item in an integration command, you can
define a map of repository item properties to attributes of the remote system’s data objects. The mapping file
controls which properties are sent as input in a Command, and what the external names of those properties are.
For details about repository item mapping, see the Repository to XML Data Binding (page 27) chapter.
Persistent Caching
The Integration Framework uses a separate SQL repository to track integration information. This SQL repository
is referred to as the persistent cache or the Integration Data repository. This repository exists to track when
particular repository item properties have been fetched from the remote system. This lets the Integration
Framework limit the frequency with which it needs to access the remote system.
The Integration Data repository has a Nucleus address of /atg/integrations/repository/
IntegrationData. You should not need to do anything to configure or use the Integration Data repository. The
repository uses a database table named if_integ_data that is created when you install ATG.
7 Integration Repository 81
The Integration Data repository defines a single item descriptor, named integration-data. For each
repository item in the local repository, there is a corresponding repository item in the Integration Data
repository. The integration-data item descriptor defines five properties:
Property Description
itemID The repository ID of the repository item in the local repository that this information
applies to.
itemDescriptor The name of the item descriptor in the local repository that this information applies
to.
repositoryName The name of the local repository.
state This property tracks whether the item in the local repository is up to date with the
data in the remote system. The state can be one of OK, INVALID, or UNKNOWN. Unless
the state is OK, then the Integration Repository tries to get the data from the remote
system, rather than relying on the local repository.
lastRun This property tracks the last time a getItem operation retrieved the item’s data from
the remote system. If the current time minus the lastRun time exceeds the local-
value-timeout value set in the Integration Repository, then this item is marked
INVALID and the Integration Repository retrieves the item’s data from the remote
system with a getItem operation.
The item descriptor definition in the Integration Repository definition file specifies a local-value-timeout
attribute:
<item-descriptor name="my-item" local-value-timeout="1000"/>
The state of a repository item can be set to one of OK, INVALID, or UNKNOWN. The state can be changed if an
Integration Repository command returns an error or times out. The Integration Repository checks the state and
lastRun values on a get-item operation. If the state is INVALID, or the lastRun time for the given command
is more than local-value-timeout milliseconds from the current time, then the item is reloaded from the
remote system (using the get-itemCommand). If an item is transient, then a transient instance of the Integration
Data repository item would be created.
An item descriptor in the Integration Repository can also define one or more read-only states. If the state of an
item in the Integration Data repository is in a read-only state, then the values in the local repository can be used
for read-only operations (query, get) but not for write operations (update, add, remove).
Cleaning up the Persistent Cache
The Integration Framework includes a scheduled service named CleanIntegrationData
(class atg.adapter.integrations.CleanIntegrationData extends
atg.service.scheduler.SingletonSchedulableService). This service is a Nucleus component
with the address /atg/integrations/repository/CleanIntegrationData. It is responsible for
cleaning up the persistent cache. The CleanIntegrationData service deletes from the Integration Data
repository any records that have not been updated since the time specified by its expireTimePeriod
82 7 Integration Repository
property. If its deleteInvalidStateItems property is set to true, then records that are not in the state
IntegrationRepository.OK will also be deleted. Note that the corresponding repository items are not
deleted from the local repository. The CleanIntegrationData component has the following configurable
properties:
Property Name Description Default Value
expireTimePeriod Time in seconds that items remain in the persistent
cache after they are last updated.
864000 (10 days)
deleteInvalidStateItems Items are deleted if their state is not OK. true
schedule See Scheduler Services in the Core Dynamo
Services chapter of the ATG Programming Guide
for information about how to set schedules in
schedulable services.
Configuration Examples
The following examples show some ways to configure three of the alternatives described in the Integration
Approaches (page 68) section:
• Configuring the Remote-Only Model (page 82)
• Configuring the Remote-then-Local Model (page 83)
• Configuring the Local-then-Remote Model (page 84)
Configuring the Remote-Only Model
The Remote Only (page 68) model is sketched in the Integration Approaches (page 68) section. In this
use case model, the data is maintained only on the remote system. Each time that the ATG application needs to
access the data, a command is issued to the remote system.
To configure this integration model, configure your Integration Repository with transient properties. None of the
repository item properties will be stored in the local repository database, so there are no table tags defined in
the local repository definition file. In addition, the local-value-timeout attribute in the item descriptors of
the Integration Repository is set to a small value. For example, the local repository definition might look like this:
localRepositoryDefinition.xml
<gsa-template> <item-descriptor name="contact" display-property="lastName"> <property name="id" data-type="string"/> <property name="firstName" data-type="string" display-name="First Name"/> <property name="lastName" data-type="string" display-name="Last Name"/> <property name="email" data-type="string" display-name="Email Address"/> </item-descriptor></gsa-template>
7 Integration Repository 83
You can define a mapping file that specifies the names of these properties on the remote system:
mapping.xml
<item-descriptor repository-path="/atg/integrations/remotex/RemoteXIntegrationRepository" name="contact"> <property name="id" targetName="Id" include="true"/> <property name="firstName" targetName="First Name" include="true"/> <property name="lastName" targetName="Last Name" include="true"/> <property name="email" targetName="Email Address" include="true"/></item-descriptor>
The Integration Repository definition file would then look like this:
integrationRepository.xml
<integration-repository-template> <item-descriptor name="contact" external-id-property="id" use-external-id="true" mapping-file="/atg/integrations/remotex/mapping.xml" local-value-timeout="1000"> <query command="/atg/integrations/remotex/GetContacts" view-class="atg.integrations.remotex.RemoteXQueryView"/> <get-item command="/atg/integrations/remotex/GetContacts" use-local-on-failure="false"/> <update-item command="/atg/integrations/remotex/UpdateContacts"/> </item-descriptor></integration-repository-template>
This configuration means that queries and getItem operations use the GetContacts command. Users cannot
remove or create contacts in the remote system, since no Command has been defined for these operations, but
can update existing ones. If the remote system is unavailable in a getItem operation, then no data is available,
since the use-local-on-failure attribute is set to false.
Note that you could change this to provide ATG with read-only access to the remote system by omitting the
updateItem Command, leaving only the GetContactsCommand to query and get items.
Configuring the Remote-then-Local Model
The Remote then Local (page 68) model is sketched in the Integration Approaches (page 68) section.
In this case, the primary source for the data is the remote system. A local copy of the data is maintained in the
local repository. Each time that the ATG application needs to access the data, a command is issued to the remote
system. If the command fails to return, then the command is issued to the local repository.
To configure this integration model, use persistent properties that are stored through the local repository in a
database on the local system. These persistent properties are defined within table tags in the local repository
item descriptors. For example:
localRepositoryDefinition.xml
<gsa-template> <item-descriptor name="contact" display-property="lastName"> <table name="contact" ... >
84 7 Integration Repository
<property name="id" data-type="string"/> <property name="firstName" data-type="string" display-name="First Name"/> <property name="lastName" data-type="string" display-name="Last Name"/> <property name="email" data-type="string" display-name="Email Address"/> </table> </item-descriptor></gsa-template>
integrationRepository.xml
The Integration Repository definition file uses the local-value-timeout attribute with a small value, so that
subsequent attempts to access an item will continue to try the remote system before resorting to the local
repository. In addition, the use-local-on-failure attribute for the getItem command is set to true.
<integration-repository-template> <item-descriptor name="contact" external-id-property="id" use-external-id="true" local-value-timeout="1000"> <query command="/atg/integrations/remotex/GetContacts" view-class="atg.integrations.remotex.RemoteXQueryView"/> <get-item command="/atg/integrations/remotex/GetContacts" use-local-on-failure="true"/> <update-item command="/atg/integrations/remotex/UpdateContacts"/> </item-descriptor></integration-repository-template>
Configuring the Local-then-Remote Model
The Local then Remote (page 69) model is sketched in the Integration Approaches (page 68) section. In
this case, a version of the data is maintained in a local repository. Only if the data is not available locally, or if the
local copy has expired or otherwise been marked invalid, do we query the remote system for the data.
To configure this integration model, use persistent properties that are stored through the local repository in a
database on the local system. The local repository is defined pretty much the same way as in the Configuring the
Remote-then-Local Model (page 83).
The Integration Repository definition is a bit different. It uses the local-value-timeout attribute with a large
value, so that items will remain valid in the local repository for a reasonable length of time.
integrationRepository.xml
<integration-repository-template> <item-descriptor name="contact" external-id-property="id" use-external-id="true" local-value-timeout="3600000"> <query command="/atg/integrations/remotex/GetContacts" view-class="atg.integrations.remotex.RemoteXQueryView"/> <get-item command="/atg/integrations/remotex/GetContacts" use-local-on-failure="true"/> <update-item command="/atg/integrations/remotex/UpdateContacts" timeout-response="UNKNOWN"/> <add-item command="/atg/integrations/remotex/AddContacts" timeout-response="INVALID"/> <remove-item command="/atg/integrations/remotex/RemoveContacts"/> </item-descriptor>
7 Integration Repository 85
</integration-repository-template>
Integration Repository Definition File
The XML definition file for Integration Repositories conforms to the integration-repository Document Type
Definition (page 89) with the URL:
http://www.atg.com/dtds/integrations/integration-repository_1.0.dtd
The definition file includes the following elements:
• integration-repository-template tag (page 85)
• header tag (page 85)
• item-descriptor tag (page 85)
• item-descriptor Child Tags (page 86)
integration-repository-template tag
The integration-repository-template tag acts as a container for the Integration Repository definition file.
It contains a single header tag and one or more item-descriptor tags.
header tag
The header tag contains information about the Integration Repository definition file. It can contain the following
child elements:
• name
• author
• version
• description
item-descriptor tag
Each item descriptor in the local repository that is integrated must be defined in the Integration Repository
definition file and configured in the item-descriptor tag. This tag has the following attributes:
Attribute Description
name The name of the item descriptor being configured. This must match the name of
the item descriptor in the local repository.
86 7 Integration Repository
Attribute Description
mapping-file This is the default mapping file that is used when sending a repository item to any
of the configured commands. The mapping file controls which properties are sent
as input, and what the external names of those properties are. See Mapping (page
80).
external-id-
property
Just as there is a local ID (repositoryId) for each item in the local repository,
there must also be an ID for each corresponding item in the remote system. This
attribute identifies which repository item property in the local repository will be
used to store the external ID. The external ID property does not have to be the
same property as the repository ID in the local repository. If it is not, set use-
external-id to false.
use-external-id If the local repository ID should match the external ID, then this property should
be set to true. If the external ID is just stored as a non-ID property on the local
item, then set this property to false.
local-value-
timeout
This property configures the number of milliseconds that a local item is valid
before it should be retrieved from the external system. For example, if this is set to
600000, and you call getItem, then each subsequent call to getItem for the next
10 minutes will return that same item with no updates. After 10 minutes, a call to
getItem will once again execute the getItem command.
read-only-states Each item retrieved from the remote system has a state associated with it in the
persistent cache. The state can be one of OK, INVALID, or UNKNOWN. The default
value is UNKNOWN. This property identifies which of those states will render the
item read-only. This is useful if you timed out on a recent call to getItem and you
still want people to be able to view the item but do not want to run the risk of
them changing it. See Persistent Caching (page 80).
allow-local-
operation
This attribute controls the behavior if there is no configured command for a
particular operation. If this attribute is true, then the local repository can act on
the local repository item without reference to the remote system. For example, if
there is no update-item command configured, and someone calls updateItem,
is this an error? Should the update just go to the local repository with no Command
execution?
item-descriptor Child Tags
The item-descriptor tag has five possible child tags:
• query Tag (page 87)
• get-item Tag (page 87)
• add-item Tag (page 88)
• update-item Tag (page 87)
• remove-item Tag (page 88)
The operations defined by these tags are also described in the Command Operations (page 77) section.
7 Integration Repository 87
query Tag
This configures the behavior of the Integration Repository when the executeQuery method is called on the
RepositoryView for items of this type.
query Tag Attributes
command
This is the Nucleus path to the Command implementation that will perform the query of the remote system.
view-class
If the default view class is not sufficient for querying items of this type, this subclass of
atg.adapter.integrations.IntegrationRepositoryView will be used for queries instead.
query-cache-size
This is the same as the SQL repository attribute of the same name. How many queries will be cached at a time?
query-expire-timeout
The time in milliseconds that each query cache entry remains valid.
get-item Tag
This configures the behavior of the Integration Repository when getItem is called for repository items of this
type.
get-item Tag Attributes
command
This is the Nucleus path to the Command implementation that will get the item from the remote system. Usually,
the Command for getting is the same as the Command for querying.
use-local-on-failure
If this attribute is set to true then a locally cached value will be used in cases that the Command fails. For
example, if the remote system is unavailable, the locally cached item will be returned to the user. If the remote
item has never been retrieved before, this attribute has no effect.
update-item Tag
This configures the behavior of the Integration Repository when updateItem is called for repository items of
this type. It can optionally contain a derived-properties Tag (page 88) as a child element. See updateItem and
Derived Properties (page 79) in the Command Operations section.
update-item Tag Attributes
command
This is the Nucleus path to the Command implementation that will update the item in the remote system.
mapping-file
If the mapping file that is defined on the item descriptor is insufficient for creating input to the update
Command, a different mapping file can be configured here. One common use for this is to exclude read-only
properties from the input.
timeout-response
This defines the behavior in response to a CommandTimeoutException thrown by the update item Command.
If this is not set, then the repository’s defaultTimeoutResponse property will be used instead. The possible
settings for this attribute are: ROLLBACK, INVALID, UNKNOWN, IGNORE. The default is ROLLBACK.
changed-properties-only
88 7 Integration Repository
If this is set to true, then only properties that have changed will be passed to the update item Command. The
external-id-property is always included.
update-local-with-result
If this is set to true, then the Integration Repository will look in the CommandResult for new property values.
Any values that appear in the result will be set on the local value of the item.
ignore-external-id-change
If this is set to true, then if the only changed property on the item is the external ID property, no call to the
update item Command will be made.
add-item Tag
This configures the behavior of the Integration Repository when addItem is called for repository items of this
type.
add-item Tag Attributes
command
This is the Nucleus path to the Command implementation that will add the item to the remote system.
mapping-file
If the mapping file that is defined on the item descriptor is insufficient for creating input to the add Command, a
different mapping file can be configured here. One common use for this is to exclude read-only properties from
the input.
timeout-response
This defines the behavior in response to a CommandTimeoutException thrown by the add item Command.
If this is not set, then the repository’s defaultTimeoutResponse property will be used instead. The possible
settings for this attribute are: ROLLBACK, INVALID, UNKNOWN, IGNORE. The default is ROLLBACK.
update-local-with-result
If this is set to true, then the Integration Repository will look in the CommandResult for new property values.
Any values that appear in the result will be set on the local value of the item.
remove-item Tag
This configures the behavior of the Integration Repository when removeItem is called for repository items of
this type.
remove-item Tag Attributes
command
This is the Nucleus path to the Command implementation that will remove the item from the remote system.
timeout-response
This defines the behavior in response to a CommandTimeoutException thrown by the remove item Command.
If this is not set, then the repository’s defaultTimeoutResponse property will be used instead. The possible
settings for this attribute are: ROLLBACK, INVALID, UNKNOWN, IGNORE. The default is ROLLBACK.
derived-properties Tag
If your underlying local repository uses the derived properties feature of the SQL repository and you have set
changed-properties-only="true" in the update-item element, then you should define a derived-
properties element to specify how the derived properties are handled. The derived-properties element
is a container for a list of derived properties mapped to some property that is used in the derivation. The
derived-properties element can optionally be used as a child element of an update-item Tag (page
87). See updateItem and Derived Properties (page 79) in the Command Operations section. See also
7 Integration Repository 89
SQL Repository Data Models: Derived Properties in the ATG Repository Guide for more information about derived
properties.
The derived-properties element contains one or more property tags.
property Tag
The property tag in the Integration Repository definition file is a child element of a derived-properties
element.
property Tag Attributes
A property tag in a derived-properties element uses the following attributes:
name The name of a property that can be derived from the referenced-property.
referenced-property The name of a derivation expression of a derived property specified by the
name attribute.
If changed-properties-only="true" in the update-item element, then whenever the referenced-
property is sent in the update command, the property specified by the name attribute will be as well. See
updateItem and Derived Properties (page 79) in the Command Operations section.
integration-repository Document Type Definition
<?xml encoding="UTF-8"?>
<!-- =============================================================== --><!-- integration-repository_1.0.dtd - Integration Repository configuration spec --><!-- @version $Id: //product/DAS/main/Java/atg/dtds/integrations/integration-repository_1.0.dtd#5 $$Change: 294774 $ --><!-- =============================================================== -->
<!-- =============================================================== The following XML attributes have a uniform meaning throughout this DTD:
(none yet)
=============================================================== -->
<!-- =============================================================== --><!-- integration-repository-configuration - top level element --><!-- =============================================================== -->
<!ENTITY % timeoutresponses "(ROLLBACK|UNKNOWN|INVALID|IGNORE)">
<!ELEMENT integration-repository-template (header?, item-descriptor*)>
<!-- The header --><!ELEMENT header (name?, author*, version?, description?)>
90 7 Integration Repository
<!-- Name of template --><!ELEMENT name (#PCDATA)>
<!-- The author(s) --><!ELEMENT author (#PCDATA)>
<!-- Version string --><!ELEMENT version (#PCDATA)>
<!-- Description string --><!ELEMENT description (#PCDATA)>
<!-- =============================================================== --><!-- integration-view element: --><!-- The definition of a view as it appears to code that calls the --><!-- integration repository. --><!-- =============================================================== -->
<!ELEMENT item-descriptor (query?, get-item?, update-item?, add-item?, remove-item?)>
<!ATTLIST item-descriptor name CDATA #REQUIRED mapping-file CDATA #IMPLIED external-id-property CDATA #IMPLIED use-external-id CDATA #IMPLIED local-value-timeout CDATA #IMPLIED read-only-states CDATA #IMPLIED allow-local-operation CDATA #IMPLIED>
<!ELEMENT query EMPTY>
<!ATTLIST query command CDATA #IMPLIED view-class CDATA #IMPLIED query-cache-size CDATA #IMPLIED query-expire-timeout CDATA #IMPLIED>
<!ELEMENT get-item EMPTY>
<!ATTLIST get-item command CDATA #IMPLIED use-local-on-failure CDATA #IMPLIED>
<!ELEMENT update-item (derived-properties?)>
<!ATTLIST update-item command CDATA #IMPLIED mapping-file CDATA #IMPLIED timeout-response %timeoutresponses; "ROLLBACK" changed-properties-only CDATA #IMPLIED update-local-with-result CDATA #IMPLIED ignore-external-id-change CDATA #IMPLIED>
7 Integration Repository 91
<!ELEMENT derived-properties (property+)>
<!ELEMENT property EMPTY>
<!ATTLIST property name CDATA #REQUIRED referenced-property CDATA #REQUIRED>
<!ELEMENT add-item EMPTY>
<!ATTLIST add-item command CDATA #IMPLIED mapping-file CDATA #IMPLIED timeout-response %timeoutresponses; "ROLLBACK" update-local-with-result CDATA #IMPLIED>
<!ELEMENT remove-item EMPTY>
<!ATTLIST remove-item command CDATA #IMPLIED timeout-response %timeoutresponses; "ROLLBACK">
8 Remote Procedure Calls 93
8 Remote Procedure Calls
The integration framework includes a facility for making remote procedure calls (RPC). The Integration
Repository makes extensive use of RPC to make calls to the remote system for querying and data
synchronization.
The RPC facility is designed to be as generic as possible in order to support a variety of remote systems and
middleware transports. The classes and interfaces in the atg.integrations package provide an API that can
be implemented in various ways to work with Web services, the Java Connector Architecture (JCA), or different
middleware transports. For example, the ATG Tibco Adapter includes an implementation of the RPC API that
enables the ATG platform to execute Tibco commands.
This chapter discusses the following topics:
RPC API Architecture (page 93)
Implementing the RPC API (page 95)
Executing Commands in Pages (page 96)
RPC API Architecture
The core pieces of the ATG RPC API architecture are:
• atg.integrations.Command interface – generic representation of a command
• atg.integrations.CommandHandler interface – executes a command, and performs pre- or
postprocessing
• atg.integrations.CommandResult class – encapsulates the results of a command
To implement the RPC API, you create classes that implement the Command or CommandHandler interface, and
return CommandResult objects. This section discusses the expected behavior of these classes. Note that some of
this behavior is not enforced by the interfaces, but is nonetheless required by the API.
For additional information about Command, CommandHandler, and CommandResult, see the ATG API Reference.
Command Interface
The atg.integrations.Command interface is a generic representation of a command. You create specific
commands by implementing this interface.
94 8 Remote Procedure Calls
The Command interface has two methods for executing commands, execute() and invokeRPC(). Both of
these methods take a java.lang.Object as input (to be as generic as possible), and return a CommandResult.
The execute() method is the one actually called by an application. Invoking this method sets off a chain of
actions that ultimately results in the invokeRPC() method being executed. The invokeRPC() method does
the actual work of making a call to the remote system. Note, however, that applications should not call this
method directly, as the processing of commands is based on the assumption that execute() is called first.
The Command.execute() method must implement the following logic:
• If the Command points to a CommandHandler (that is, if the Command.commandHandler
property is not null), pass the Command and its input to that CommandHandler by calling the
CommandHandler.executeCommand() method.
• If the Command does not point to a CommandHandler, call the Command.invokeRPC() method.
CommandHandler Interface
The atg.integrations.CommandHandler interface is a generic representation of a handler class for
preprocessing and postprocessing commands. Command handlers are not a required part of the RPC API, since
a Command.execute() method can call the corresponding Command.invokeRPC() method directly. However,
command handlers add a great deal of power and flexibility to the RPC system.
To pass a Command and its input to a CommandHandler, the Command.execute() method calls the
CommandHandler.executeCommand() method. The CommandHandler.executeCommand() method must
implement the following logic:
• If the CommandHandler points to another CommandHandler (that is, if the
CommandHandler.nextCommandHandler property is not null):
• Perform any preprocessing.
• Pass along the Command and its input to the next CommandHandler by calling
CommandHandler.getNextCommandHandler().executeCommand().
• Perform any postprocessing.
• If the CommandHandler does not point to another CommandHandler:
• Perform any preprocessing.
• Execute the Command.invokeRPC() method.
• Perform any postprocessing.
This logic allows command handlers (and the services they implement) to be chained together. The final
CommandHandler in the chain must be able to call the Command.invokeRPC() method, to ensure that the
command can be executed. However, it is not required that the command is always executed. For example, one
typical use for a command handler is caching of commands and their results. Such a command handler might
work like this:
• Examine the command to determine if it is in the cache.
• If the command is in the cache, return the cached result.
• If the command is not in the cache, execute the command, return the result, and cache the command and
result.
8 Remote Procedure Calls 95
CommandResult Class
When a Command or CommandHandler object executes a Command, it must return a CommandResult. A
CommandResult is just a container that has two other objects as properties:
• The result property is a java.lang.Object that is the actual object returned by the remote call.
• The context property is a java.util.Map that can be used to store additional parameters and their values.
Application code should access the results in the result object by using the DynamicBeans API. For example,
suppose the RPC call adds two integers and stores the result as an integer named sum. The application code
could obtain the value of sum like this:
Integer sum = (Integer) DynamicBeans.getPropertyValue(getCommandResult.getResults(),"sum");
The DynamicBeans API is recommended because it eliminates the need to convert the object returned from the
transport RPC into a generic data format, which requires additional memory and processing time. For example,
if a query returns a DOM object, the DynamicBeans API can be used to access the data directly from it, avoiding
the need to copy the properties from the DOM object to another object type (such as a Map).
RPC implementations are not required to use the contextMap. It is included in the CommandResult object to
provide a way to store additional information that is not part of the result object.
Implementing the RPC API
As mentioned above, the RPC API is intended to be as generic as possible so implementations can support
a wide variety of transports and remote systems. However, this flexibility also puts a lot of burden on the
implementer. To simplify the process, the atg.integration package includes basic implementations of the
Command and CommandHandler interfaces. Rather than implementing the interfaces directly, you can just
extend the BaseCommand and BaseCommandHandler classes.
The atg.integrations.BaseCommand class provides an execute() method that implements the logic
described in the Command Interface (page 93) section above. Classes that extend this class must provide
their own implementations of the invokeRPC() method.
The atg.integrations.BaseCommandHandler class provides an executeCommand() method that
implements the logic described in the CommandHandler Interface (page 94) section above. Classes that
extend this class can override the executeCommand() method to do their pre- or postprocessing as needed.
Implementing this method can be simplified by having the executeCommand() method of the subclass call the
executeCommand() method of the parent class while adding pre- or postprocessing of its own. For example, a
CachingCommandHandler class might look like this:
Public class CachingCommandHandler extends BaseCommandHandler { Map sCache = new HashMap(); // Cache of method invocations.Public CommandResult executeCommand(Command pCommand, Object pInput) { if (sCache.containsKey(pInput)) { return sCache.get(pInput); }else {
96 8 Remote Procedure Calls
CommandResult result = super.executeCommand(pCommand, pInput); sCache.put(pInput, result); return result; }}}
For more information about BaseCommand and BaseCommandHandler, see the ATG API Reference.
Exception Handling
The Command.execute(), Command.invokeRPC(), and CommandHandler.executeCommand() methods
must throw exceptions of class atg.integration.CommandInvocationException. This exception is
intended to wrap any underlying exceptions that might be thrown by a particular transport or remote system.
This exception must wrap the underlying exception, rather than copying its message, so that stack trace
printouts include the information from the underlying exception.
The CommandInvocationException class has two useful subclasses:
• atg.integration.CommandTimeoutException can be thrown when an RPC call times out. This is a special
case, since a timeout doesn’t indicate whether the RPC call succeeded or not.
• atg.integration.InvalidInputException can be thrown if the input object passed to the Command is
invalid.
Executing Commands in Pages
You can use the atg.integrations.MapRPCDroplet servlet bean to execute RPC commands in JavaServer
Pages. This servlet bean executes a command and, depending on whether the command is executed
successfully, renders either its output open parameter or its error open parameter. If the command is executed
successfully, the result output parameter is set to the result of the command, and the output open parameter
is rendered. If an exception is thrown, the exception output parameter is set to the exception, and the error
open parameter is rendered.
The command input parameter takes an object that implements the atg.integrations.Command interface.
The inputParameters parameter supplies the inputs to the command as a java.util.Map of parameter
name/value pairs.
As an alternative to specifying these values in pages, MapRPCDroplet has command and inputParameters
properties that you can use to specify these values in the servlet bean’s properties file. Note, however, that you
cannot specify the same parameter both in the properties file and in a page. If you do this, MapRPCDroplet
throws a ServletException.
MapRPCDroplet also takes an inputParameterNames parameter that you can use to specify the input names
as a list of page parameters, and then use those page parameters to specify the input values. For example:
<dsp:param name="inputParameterNames" value="first_name,age"/><dsp:param name="first_name" value="Bill"/><dsp:param name="age" value="43"/>
8 Remote Procedure Calls 97
You cannot include both the inputParameters and the inputParameterNames parameter in the same page,
or include inputParameterNames in the page if inputParameters is specified in the servlet bean’s properties
file.
However, there is a way you can specify default values for the command parameters in the servlet bean’s
properties file, and then optionally override these values in pages. To do this:
• Use the inputParameters property to specify the command parameters and their default values.
• In your pages, define page parameters with the same names as the command parameters.
The values specified for the page parameters override the values in the properties file, and are used when the
command is invoked. If a command parameter has no corresponding page parameter, the default value from the
properties file is used.
Input Parameters
command
The command to execute. Must be an instance of a class that implements the
atg.integrations.Command interface. This parameter can either be defined in a page or
by setting the command property of the servlet bean, but it cannot be defined both ways.
inputParameters
The inputs to pass to the command, supplied as a java.util.Map of parameter name/value
pairs. This parameter can either be defined in a page or by setting the inputParameters
property of this servlet bean, but it cannot be defined both ways.
inputParameterNames
A comma-separated list of command input parameter names. Each name defines a page
parameter whose name and value (specified in the page) are used to supply one of the
inputs to the command.
parameter names
Page parameters that correspond to the names of command input parameters specified in
inputParameterNames.
Output Parameters
result
The result object from the command, if the execution is successful.
exception
The exception thrown by the command, if the execution is unsuccessful.
Open Parameters
output
Rendered if the command is executed successfully.
error
Rendered if the command throws an exception.
Example
The following example uses inputParameterNames to create a UserId page parameter, and then sets its value
to the value of a profile ID. This parameter name/value pair is passed as an input to the command. Depending
98 8 Remote Procedure Calls
on whether the command is executed successfully, Dynamo renders either the output open parameter or the
error open parameter.
<dsp:droplet bean="/atg/integrations/MapRPCDroplet"> <dsp:param name="command" value="bean:/atg/integrations/jdbc/QueryForUser"/> <dsp:param name="inputParameterNames" value="UserId"/> <dsp:param name="UserId" value="bean:Profile.Id"/> <dsp:oparam name="output"> <p>The user's email address is: <dsp:valueof param="result.emailAddress"/> </dsp:oparam> <dsp:oparam name="error"> <p>Unable to execute query. The following exceptions occurred: <dsp:valueof param="exception"/> </dsp:oparam></dsp:droplet>
Part III. ATG Platform REST Web ServicesIn addition to the ATG Web services functionality discussed in the preceding chapters, the ATG platform includes REST Web
Services that expose the features in the ATG Adaptive Scenario Engine in a RESTful manner.
The ATG Adaptive Scenario Engine provides an open, server-side environment for building and deploying dynamic,
personalized applications for the Web and other communication channels, such as email and wireless devices. The core of
the platform is the Dynamo Application Framework (DAF), which implements a component development model based on
JavaBeans and JavaServer Pages (JSPs). Developers assemble applications out of component beans (based on standard ATG
classes or custom Java classes) by linking them together through configuration files in Nucleus, ATG’s open object framework.
Page designers build the front-end interface for the application out of JavaServer Pages that use ATG’s DSP tag library. The
DSP tag library makes it possible to embed Nucleus components in JSPs, and use those components for rendering dynamic
content.
Traditionally ATG has used form handlers to process form input and JSP (JHTML) to handle page generation. The addition of
RESTful web services allows customers to use popular technologies like Flash, Flex, PHP, and Python for page generation and
form handling.
Note: The ATG Platform REST Web Services described in this section are not related to the SOAP-based web services
described previously in this guide. The REST and SOAP modules do not share any functionality. You should not assume
that anything which you may know about ATG SOAP Web Services will relate to ATG Platform REST Web Services. The two
technologies were developed independently and are quite different in their implementations.
The ATG Platform REST Web Services allow developers to
• Retrieve and change data in the server
• Call public methods on Nucleus components
• Call form handler functionality
• Manipulate repository data including creating and deleting items
• Use JSON or XML formats for sending or receiving data from the server
• Filtering and alias properties
• Use client side APIs written in Java and ActionScript to facilitate web services calls
The chapters in this section discuss how to use the ATG Platform REST Web Services functionality to communicate with an
ATG server:
Getting Started (page 101)
Client Libraries (page 103)
Working with Components (page 113)
Calling Methods (page 115)
Working with Repository Items (page 121)
Input and Output Formats (page 125)
Property Filtering (page 129)
Security (page 41)
9 Getting Started 101
9 Getting Started
This chapter describes how to get up and running with the ATG Platform REST Web Services as quickly as
possible.
Starting the ATG Server with the REST Module
First, install the ATG Platform REST Web Services module by extracting the archive (zip/jar) into your ATG root
directory. Once extracted, you should see a new folder/directory called REST. Next, start your ATG server with
the REST module. If you rely on other modules, those can remain in your startup list. For detailed instructions on
assembling ATG applications, see the ATG Programming Guide.
Setting the Default ACL for REST Security
Once the server is running with the REST module, your platform is now able to accept and process REST
requests. Before you begin coding, you must configure the Web services security component. By default:
• The security components in the ATG Platform REST Web Services require you to be logged into the server in
order to make calls.
• No users have access to any components, so even a logged-in user will not be able to successfully make any
REST requests.
In a development environment, you can set a default ACL in the security configuration file. This allows all the
specified users to have access to all Nucleus components.
Important: This functionality is provided for convenience and should not be used in a production environment
unless that is the specified intent.
To set a default ACL in the security configuration layer, create a file in your localconfig directory at atg/
rest/security named restSecurityConfiguration.xml. Add the following lines to the file, replacing
#username# with the name of a valid profile for logging onto your ATG system.
<programlisting> <rest-security> <default-acl value="Profile$login$#username#:read,write,execute"/> </rest-security>
102 9 Getting Started
</programlisting>
For more information about configuring the security component, see the Security (page 41) chapter.
Configuring the Web Services
You configure the ATG Platform REST Web Services by setting configuration parameters on the /atg/rest/
Configuration component. For more information, see Control Parameters (page 137).
Creating Simple Applications
Now you are ready to create your first application that communicates with the server in a RESTful manner. For
sample applications that login and logout and access data from the server, read the following chapter, Client
Libraries (page 103).
10 Client Libraries 103
10 Client Libraries
The ATG Platform REST Web Services package includes two client libraries:
• Java Client Library (page 103)
• ActionScript Client Library (page 111)
These libraries make ATG Platform REST Web Services easier to use by hiding all the complexity of creating
connections, assembling payloads for requests, and processing responses.
Java Client Library
The Java client library provides a number of classes that assist in making REST calls to the ATG Platform REST
Web Services.
The following classes are the ones you’ll use most often:
RestSession
Handles login and logout, manages connections, and issues requests.
RestResult
Accesses the RestResult object that is returned when a request is made to the server. This class also includes
convenience methods for retrieving the response data.
RestComponentHelper
Contains a series of static helper methods that simplify issuing Nucleus component calls to the server.
RestRepositoryHelper
Contains a series of static helper methods that simplify issuing repository calls to the server.
Creating Requests
You will find it easiest to make most ATG Platform REST Web Services requests with the use the
RestComponentHelper and RestRepositoryHelper classes. These two classes simplify calling into the server
by providing methods which hide the complexity of assembling the data for the request. All the methods for
both classes are static and each returns a RestResult object and throws RestClientException. See the
Javadoc for more information about each method.
104 10 Client Libraries
atg.rest.client.RestComponentHelper
The methods of the RestComponentHelper class allow access to components, properties, and methods. Each
of the methods accepts a Map of parameters, which control the request. For more information and examples,
see Working with Components (page 113).
• public static RestResult getComponent(String pComponentPath, Map<String,Object>
pParams, RestSession pSession)
Returns all the properties of the specified Nucleus component.
• public static RestResult getPropertyValue(String pComponentPath, String pProperty,
Map<String,Object> pParams, RestSession pSession)
Returns the requested property from the specified Nucleus component.
• public static RestResult setPropertyValue(String pComponentPath, String pProperty,
Object pValue, Map<String,Object> pParams, RestSession pSession)
Sets a value on the specified Nucleus component property.
• public static RestResult executeMethod(String pComponentPath, String pMethodName,
Object[] pArguments, Map<String,Object> pParams, RestSession pSession)
Calls a public method on the specified Nucleus component.
The Object[] pArguments parameter is an array of method arguments. This parameter should
contain one Object for each of the method parameters. For example, if the method takes an int, then a
java.lang.Integer object should be passed. The Java client library handles converting the object for
transport to the server and the ATG REST module handles converting it to an int. If any parameter object is
passed as a String, the parameter will be transported to the server without any changes. This means that a
method that takes an int can have a java.lang.String object with a value of 2, for example, passed. For
parameters that are complex objects, the object can be passed as a parameter and the library will attempt
to convert it for transport. When the request is sent to the server, a new instance will be constructed and its
properties populated with the values from the original object. Collections and Maps can also be transported.
For more information, see Calling Methods (page 115).
atg.rest.client.RestRepositoryHelper Class
The methods of the RestRepositoryHelper class allow you to access repository items, execute RQL queries,
retrieve individual property values, set property values, create items, and remove items. Each of the methods
takes a Nucleus repository path and item descriptor name as its first two arguments, as well as a Map of
parameters, which control various aspects of the request. For more information and examples, see Working with
Repository Items (page 121).
• public static RestResult createItem(String pRepositoryPath, String
pItemDescriptorName, Map<String,Object> pParams, RestSession pSession)
Returns the ID of the newly created repository item.
• public static RestResult createItem(String pRepositoryPath, String
pItemDescriptorName, String pItemId, Map<String,Object> pParams, RestSession
pSession)
Returns the ID of the newly created repository item.
10 Client Libraries 105
• public static RestResult removeItem(String pRepositoryPath, String
pItemDescriptorName, String pItemId, Map<String,Object> pParams, RestSession
pSession)
Returns true if the repository item was successfully removed; otherwise, returns false.
• public static RestResult getItem(String pRepositoryPath, String pItemDescriptorName,
String pItemId, Map<String,Object> pParams, RestSession pSession)
Returns the contents of the repository item. If any of the properties are references to other items, Collections,
arrays, or Maps, returns a REST URL that you can use to access the contents of the specific property. You can
create a raw REST request to access the data for the property. For more information, see Creating a Raw REST
Request (page 109).
• public static RestResult getItems(String pRepositoryPath, String
pItemDescriptorName, Map<String,Object> pParams, RestSession pSession)
Returns a series of URLs, one for each item which is being returned. T to control the number of items returned,
the atg-rest-index and atg-rest-count parameters can be passed into the pParams argument.
• public static RestResult executeRQLQuery(String pRepositoryPath, String
pItemDescriptorName, String pRQL, Map<String,Object> pParams, RestSession pSession)
Returns a series of URLs, one for each item which is being returned. T to control the number of items returned,
the atg-rest-index and atg-rest-count parameters can be passed into the pParams argument.
• public static RestResult getPropertyValue(String pRepositoryPath, String
pItemDescriptorName, String pItemId, String pProperty, Map<String,Object> pParams,
RestSession pSession)
Returns the value of the requested property. If the property is a Collection, Map, array, or reference to another
repository item, returns a URL.
• public static RestResult setPropertyValue(String pRepositoryPath, String
pItemDescriptorName, String pItemId, String pProperty, Object pValue,
Map<String,Object> pParams, RestSession pSession)
Creating a RestSession Object
The ATG Platform REST Web Services calls are executed within the context of an HTTP session. This enables a
client application to maintain state across requests and to use login information for security purposes.
The RestSession class contains all the logic required for connecting and communicating with an ATG server.
The following code creates a new RestSession object:
RestSession session = RestSession.createSession(host, port, username, password);
RestSession class properties
The RestSession class includes the following properties. Some are set when the object is created and others
can be changed after the object has been constructed:
106 10 Client Libraries
Property Description
Hostname The name of the host which the session will or is connected to. Default is
localhost.
Port The port number which the session will use. Default is 80.
Username The username the session will use to connect.
Password The password the session will use to connect.
Scheme The scheme the session will use to connect. Default is HTTP expect for login
calls.
restContextRoot The web application context root for ATG Platform REST Web Services. Default is
/rest.
useInternalProfileForLoginTells the session object to login as an internal user instead of a profile user. You
will probably need to change this property after the RestSession object is
created and before login is called. When connecting to a server that can be
accessed only by internal users, this property must be set to true or the login
will fail.
useHttpsForLogin Tells the session object to use the HTTPS scheme for login calls. Default is true.
httpsPort The HTTPS port number which the session will use. Default is 443.
userId The userId of the connected user. This value is set after logging in.
sessionId The session ID of the current session. This value is set after logging in.
Encoding The encoding to use when encoding parameter values. Default is UTF
inputFormat The default input format that is set on the server. Changing this value has no
effect on the server.
outputFormat The default output format that is set on the server. Changing this value has no
effect on the server
Logging in and Logging Out
The following code sample is a shell of a simple application. It does nothing more than login and logout. The
most interesting portion of the following code sample is the execute method.
The sample first creates a RestSession object. It does this by calling the static
RestSession.createSession() method. The parameters to createSession are the hostname, port,
username, and password. By default all login calls are issued with HTTPS. If you do not want this functionality,
set the value of the useHttpsForLogin flag to false on the session object, as the following sample does. The
next section of code calls the login() method on the RestSession object. If the login attempt fails, then
a RestClientException is thrown. The last section of code calls the logout() method and concludes the
session.
import atg.rest.client.RestClientException;
10 Client Libraries 107
import atg.rest.client.RestComponentHelper; import atg.rest.client.RestResult; import atg.rest.client.RestSession;
import java.io.IOException;
public class RestClientSample {private String mUsername = null;private String mPassword = null;private String mHost = "localhost";private int mPort = 80;private RestSession mSession = null;
public RestClientSample() {}
protected void parseArguments(String[] pArgs) throws Exception { for (int i = 0; i < pArgs.length; i++) { String arg = pArgs[i];
if (arg.equals("-user")) mUsername = pArgs[i+1]; else if (arg.equals("-password")) mPassword = pArgs[i+1]; else if (arg.equals("-host")) mHost = pArgs[i+1]; else if (arg.equals("-port")) mPort = Integer.parseInt(pArgs[i+1]); }
if (isBlank(mUsername)) throw new Exception("Must supply username"); if (isBlank(mPassword)) throw new Exception("Must supply password");}
protected boolean isBlank(String pStr) { return (pStr == null || pStr.length() == 0 || pStr.trim().length() == 0);}
protected void println(String s) { System.out.println(s);}
protected void println(Throwable t) { t.printStackTrace(System.out);}
protected void execute() throws RestClientException { mSession = RestSession.createSession(mHost, mPort, mUsername, mPassword); mSession.setUseHttpsForLogin(false);
try { mSession.login(); println("Login Successful"); }
catch (Throwable t) { println(t); }
108 10 Client Libraries
finally { try { mSession.logout(); println("Logout Successful"); } catch (RestClientException e) { println(e); } }}
/** * @param args */public static void main(String[] args) { RestClientSample sample = new RestClientSample();
try { sample.parseArguments(args); sample.execute(); } catch (Throwable t) { sample.println(t); }} }
Accessing Data from the Server
Now you can build on the previous example by accessing a Nucleus component property.
The example that follows makes a request for all the properties of a Nucleus component using the
RestComponentHelper class. This class has several static convenience methods which assist in creating the
requests and issuing them to the server. The getComponent() method take the path to a Nucleus component,
a map of optional parameters, and the RestSession object and returns a RestResult object.
The RestResult object can be used to access the data from the response. The following sample calls
readInputStream() to return a String of the response data. In this case, you can assume that the server is
using the default output format which is JSON. The string in response data will contain the JSON output. A JSON
object is then constructed and output.
Another alternative is to simply output responseData, but this sample illustrates how you might use the
output. Similarly, if the output format was XML, you could create an XML document object using dom4j.
The finally block includes a call to close the result. Doing this will release the underlying connection
resources. If this call is omitted, the next call to the server using the same RestSession object will close the
result.
protected void execute() throws RestClientException { RestResult result = null;
mSession = RestSession.createSession(mHost, mPort, mUsername, mPassword); mSession.setUseHttpsForLogin(false);
try {mSession.login();println("Login Successful");
10 Client Libraries 109
result = RestComponentHelper.getComponent("/atg/dynamo/Configuration", null,mSession);String responseData = result.readInputStream();if (responseData != null) { JSONObject json = new JSONObject(responseData); println(json.toString());} } catch (Throwable t) {println(t); } finally {if (result != null) result.close();
try { mSession.logout(); println("Logout Successful");}catch (RestClientException e) { println(e);} } }
Creating a Raw REST Request
The RestComponentHelper and RestRepositoryHelper classes might not support every type of request you
want to issue to the server. If this is the case, you can issue a request using the createHttpRequest() method
of the RestSession class. There are two versions of this method:
public RestResult createHttpRequest(String pURL, Map<String,Object> pParams, String pMethodType)
public RestResult createHttpRequest(String pURL, Map<String,Object> pParams, Object[] pArguments, String pMethodType)
The following table describes the arguments for each version of this method.
Argument Description
pURL The URL to request, formatted as
http://hostname:port/uri
The pURL argument must be an absolute URL, including the hostname (and
port, if it is not 80). The RestSession class includes a convenience method
called getHostString() which returns a string containing the scheme, host,
and port number. The caller can then append the remainder of the URL and
pass the resulting string as the first argument to this method.
110 10 Client Libraries
Argument Description
pParams A Map of parameters to submit along with the request.
This argument is the same as it would have been if you made the request using
either of the helper classes. It contains parameters which can control certain
aspects of the request.
pArguments An array of Objects which contain the method parameter values.
Use this argument only for method calls.
The value is the same as it would be if calling the executeMethod() method
on the RestComponentHelper class.
pMethodType The HTTP method for the request: GET, POST, PUT, or DELETE.
The atg.rest.client.RestConstants class contains constant values for
these strings. In short, GET should be used when retrieving data, POST should
be used when calling methods, PUT should be used when setting properties,
and DELETE is used for deleting repository items. DELETE is not used when
interacting with Nucleus components.
Handling Results
createHttpRequest() and all the helper class methods return a RestResult object that allows
access to various parts of the response. The most interesting and useful method on the RestResult is
readInputStream(). This is a convenience method which will return the response data into a String
public String readInputStream() throws IOException
After calling this method the String object which is returned will contain the JSON or XML with the content
which was requested. The REST module uses the org.json.jar library and the dom4j XML library internally.
You can also use these libraries, or comparable libraries, in your applications.
If the response data is large, you can access the input stream directly by calling getInputStream() on the
RestResult.
Other useful methods on the RestResult object are getResponseCode() and getResponseMessage().
These return the response’s response code and message, respectively. For more information, see HTTP Status
Codes (page 139).
The Java client library uses the java.net.HttpURLConnection class to communicate with servers. To access
any functionality that the RestResult does not expose, call the getConnection() method to return the
underlying HttpURLConnection object.
When you are finished with the RestResult object, it is good practice to call the close() method. This
releases any resources that the HttpURLConnection might hold. If the connection is not closed, the next
request to the server will close the HttpURLConnection.
10 Client Libraries 111
ActionScript Client Library
ActionScript is the programming language for the Adobe Flash Player run-time environment. This library is
useful for client applications written in Adobe Flash or Adobe Flex.
Note: The ATG Platform REST Web Services were tested with ActionScript 3.
The ActionScript client library is nearly identical in structure to the Java client library. The main difference
between the two libraries is the way they handle results:
• The Java client library uses the RestResult class to handle results.
• The ActionScript library does not include a RestResult class; instead, it handles results using a callback
mechanism. Therefore, helper class methods and the createHttpRequest() method for the ActionScript
client library take a result handler and fault/error handler functions as arguments.
The following code sample illustrates how the ActionScript client library handles results.
public function getPropertyValue():void {RestComponentHelper.getPropertyValue("/atg/dynamo/Configuration", "httpPort",null, session, handleResult, handleFault); // get the httpPort property from the Configuration component}
public function handleResult(pEvent:Event):void { var xml:XML = new XML(pEvent.target.data); // create an XML object populateGridWithXML(xml); // populate the control with the XML output}
public function handleFault(pEvent:Event):void { Alert.show("Fault"); // display an error dialog}
atg.rest.client.RestComponentHelper
The RestComponentHelper class simplifies Nucleus requests.
The RestComponentHelper methods are written in ActionScript as follows. For details about individual class
methods, refer to the Java Client Library (page 103) section.
public static function getComponent(pComponentPath:String, pParams:Array,
pSession:RestSession, pResultHandler:Function,
pFaultHandler:Function):void
public static function getPropertyValue(pComponentPath:String, pProperty:String,
pParams:Object, pSession:RestSession,
pResultHandler:Function, pFaultHandler:Function):void
public static function setPropertyValue(pComponentPath:String, pProperty:String,
pValue:Object, pParams:Object,
pSession:RestSession, pResultHandler:Function, pFaultHandler:Function):void
112 10 Client Libraries
public static function executeMethod(pComponentPath:String, pMethodName:String,
pArguments:Array, pParams:Object,
pSession:RestSession, pResultHandler:Function, pFaultHandler:Function):void
atg.rest.client.RestRepositoryHelper
The RestRepositoryHelper class simplifies repository requests.
The RestRepositoryHelper class methods are written in ActionScript as follows. For details about individual
class methods, refer to the Java Client Library (page 103) section.
public static function getItem(pRepositoryPath:String, pItemDescriptorName:String,
pItemId:String,
pParams:Object, pSession:RestSession, pResultHandler:Function,
pFaultHandler:Function):void
public static function getItems(pRepositoryPath:String, pItemDescriptorName:String,
pParams:Object, pSession:RestSession,
pResultHandler:Function, pFaultHandler:Function):void
public static function executeRQLQuery(pRepositoryPath:String,
pItemDescriptorName:String, pRQL:String,
pParams:Object, pSession:RestSession, pResultHandler:Function,
pFaultHandler:Function):void
public static function getPropertyValue(pRepositoryPath:String,
pItemDescriptorName:String, pItemId:String, pProperty:String,
pParams:Object, pSession:RestSession, pResultHandler:Function,
pFaultHandler:Function):void
public static function setPropertyValue(pRepositoryPath:String,
pItemDescriptorName:String, pItemId:String, pProperty:String,
pValue:Object, pParams:Object, pSession:RestSession, pResultHandler:Function,
pFaultHandler:Function):void
public static function createItem(pRepositoryPath:String, pItemDescriptorName:String,
pParams:Object, pSession:RestSession,
pResultHandler:Function, pFaultHandler:Function):void
public static function createItemWithId(pRepositoryPath:String,
pItemDescriptorName:String, pItemId:String,
pParams:Object, pSession:RestSession, pResultHandler:Function,
pFaultHandler:Function):void
public static function removeItem(pRepositoryPath:String, pItemDescriptorName:String,
pItemId:String,
pParams:Object, pSession:RestSession, pResultHandler:Function,
pFaultHandler:Function):void
11 Working with Components 113
11 Working with Components
Nucleus components are server-side JavaBeans and servlets that perform the back-end functionality of the Web
application—for example, enabling database connectivity, logging, scheduling, and handling HTTP requests.
The ATG Platform REST Web Services RestComponentHelper class exposes methods that get component data
and get and set component property values. You cannot use the ATG Platform REST Web Services to delete
components.
This chapter discusses the following topics:
Getting Component Data (page 113)
Getting and Setting Property Values (page 114)
A Note about Output Format
All RestComponentHelper methods return results in the format that is configured as the default on the server
(JSON or XML). To override the default for a specific method, add the atg-rest-output parameter to the
pParams argument with a suitable value (“xml”, “json”, or the identifier for an appropriate output customizer).
For more information, refer to the Input and Output Formats (page 125) section.
A Note about Nucleus Component Security
ATG Platform REST Web Services allow you to secure Nucleus components at multiple levels of granularity. For
details about securing Nucleus components, refer to the Security (page 41) chapter.
Getting Component Data
The getComponent() method of the RestComponentHelper class returns a data stream that contains a
representation of a component.
The following code sample returns the Configuration component:
114 11 Working with Components
RestResult result = RestComponentHelper.getComponent("/atg/dynamo/Configuration",null, mSession)
Getting and Setting Property Values
The getPropertyValue() method of the RestComponentHelper class returns a data stream that contains the
value of the specified property.
The following code sample gets the value of the property httpPort from the Configuration component.
RestResult result = RestComponentHelper.getPropertyValue("/atg/dynamo/Configuration", "httpPort",params, session)
Use the RestComponentHelper.setPropertyValue() method to set property values on Nucleus
components. The following code sample sets the value of the Configuration component property httpPort to
8580.
RestResult result = RestComponentHelper.setPropertyValue("/atg/dynamo/Configuration", "httpPort","8580", params, session)
12 Calling Methods 115
12 Calling Methods
You can use the ATG Platform REST Web Services to call public methods on Nucleus components. If a
method is overloaded, then the server will attempt to determine which method to call by looking at the
number of arguments supplied. It is also possible to supply a method signature as a parameter to the
RestComponentHelper.executeMethod() method. Supplying the atg-rest-method parameter allows
you to specify the exact method to be called. The value of the parameter should be the Java method signature
of the method to call. You can find the method signature for a method by using the javap command, which
disassembles a class file. (The javap command is part of the JDK.)
Depending on the return type of the method, the output will vary. If the output is an object, then it will return a
JSON or XML stream which contains the values of all the properties in the object. If it is a simple type like an int
or a String, it will return the value. The identifier for the return type is atgResponse.
Passing Parameters to Methods
If you use the Java or ActionScript client libraries that ship with the ATG Platform REST Web Services,
passing parameters to methods is as simple as supplying the Objects in the pArguments argument for the
RestComponentHelper.executeMethod() method. For more information, see Client Libraries (page 103).
If one of the parameters is a simple type, then it should be wrapped in an object. For example, an int will
become a java.lang.Integer, a boolean becomes a java.lang.Boolean, and so on.
When you pass collections, Maps, and arrays as parameters, the client library attempts to convert those types.
Date, Time, and Timestamp objects can also be passed, as shown in the following sample.
RestResult result = RestComponentHelper.executeMethod("/some/Component", "aMethod", new Object[] {1,2,3,4.4,5.5,true,'a',0xa}, null, session)
In order to pass repository items, use a preformatted string that takes the format of
repository Nucleus path:item descriptor name:item id
For example:
/atg/commerce/catalog/ProductCatalog:product:prod12345
When you reference a repository item this way, the server performs a lookup and uses the item as the method
argument. For example:
116 12 Calling Methods
RestResult result = RestComponentHelper.executeMethod("/some/Component","aMethod", new Object[] {"/atg/commerce/catalog/ProductCatalog:product:prod12345"}, null, session)
If a method takes a GenericService as an argument, simply passing the Nucleus path as a string will cause the
server to lookup the Nucleus component and use it as the method argument. For example:
RestResult result = RestComponentHelper.executeMethod("/some/Component","aMethod", new Object[] {"/atg/dynamo/Configuration"}, null, session)
If passing a complex Java object, attempt to add the object to the pArguments argument and call the method.
In most cases, the argument will not need to be transformed before it is transported to the server. The client
library will make an attempt at converting the object for you.
MyObject myObject = new MyObject();RestResult result = RestComponentHelper.executeMethod("/some/Component","aMethod", new Object[] {myObject}, null, session)
Calling Handler Methods
Form handlers use special handler methods for linking form elements with Nucleus components. One of the
more powerful features in the ATG Platform REST Web Services module is the ability to call handler methods.
If you have existing JSP-based applications, all the functionality which has previously been exposed in those
applications can be reused with REST based applications. Use RestComponentHelper.executeMethod() to
call handler methods.
Keep the following in mind when calling a handler method
• The method name, the second argument in the executeMethod() method, should not contain the “handle”
prefix. For example, to call the handleCreate method, it should be specified simply as create in the
pMethodName argument.
• The pArguments parameter should always be null when you call a handler method.
The following code sample calls the handleCreate method on a specified form handler:
RestResult result = RestComponentHelper.executeMethod("/some/FormHandler","create", null, null, session)
As long as a form handler does not submit a redirect, the execution would be similar to a regular method call.
For those form handler methods which do redirect, the redirect will be intercepted and returned back to the
client as an exception.
12 Calling Methods 117
Passing Parameters to Form Handlers
Form handler parameters which need to be supplied should be added to the params argument. In a JSP page
these parameters would be the input tags in a JSP form. The following example calls the handleCreate()
method on a form handler. The inputs to the form handler are a first and last name.
Map<String,String> params = new HashMap<String,String>();params.put("firstName", "Andy");params.put("lastName", "Jones");RestResult result = RestComponentHelper.executeMethod("/some/FormHandler","create", null, params, session);
Calling Methods with ActionScript
The ActionScript client library’s RestClientHelper class includes the following helper methods, which convert
arrays, iLists, and Objects to MultiValue objects:
public static function convertArrayToMultivalue(pValue:Array, pMultiValueType:String,
pComponentType:String, pFormat:String, pSession:RestSession):String
public static function convertIListToMultivalue(pValue:IList, pMultiValueType:String,
pComponentType:String, pFormat:String, pSession:RestSession):String
public static function convertObjectToMultivalue(pValue:Object,
pMultiValueType:String,
pKeyType:String, pValueType:String, pFormat:String, pSession:RestSession):String
The following table describes the arguments for each of these methods.
Argument Description
pMultiValueType The absolute path of a Java class, such as java.util.ArrayList. Be sure to specify a
valid class name and not an interface name.
pComponentType The class type of the component to instantiate for each element in the
multivalued type. For example, an array of integers in ActionScript could be
converted to an ArrayList of java.lang.Integer objects.
pFormat The server’s input format type. This can be retrieved from the session object’s
inputFormat property..
pKeyType
pValueType
ActionScript objects act as associative arrays (similar to java Maps), the
convertObjectToMultivalue() method takes a key type and value type.
These arguments are similar to pComponentType and are absolute names of
Java classes to use for the key and value objects in the Java Map.
118 12 Calling Methods
Similar to the Java client library, passing arguments to methods is generally straightforward. For primitive types,
just add them to the pArguments array.
var result:RestResult = RestComponentHelper.executeMethod("/some/Component", "aMethod", [1,2,3,4.4,5.5,true,'a',0xa], null, session, handleResult, handleFault)
To pass a reference to a repository item, use the format
<repository path:item descriptor name:item id>
For example:
var result:RestResultRestComponentHelper.executeMethod("/some/Component","aMethod", ["/atg/commerce/catalog/ProductCatalog:product:prod12345"], null,session, handleResult, handleFault)
To pass a reference to a Nucleus component, pass the Nucleus component path. For example:
var result:RestResultRestComponentHelper.executeMethod("/some/Component","aMethod", ["/atg/dynamo/Configuration"], null, session, handleResult,handleFault)
The following example is a call to a method which takes a repository item array and a GenericService array.
<programlisting>var result:RestResultRestComponentHelper.executeMethod("/some/Component","aMethod",[["/atg/commerce/catalog/ProductCatalog:product:prod12345","/atg/commerce/catalog/ProductCatalog:product:prod67890"],["/atg/dynamo/Configuration","/atg/dynamo/Configuration"]], null, session, handleResult, handleFault)
As mentioned above, arrays, ILists, and Objects must be converted before being passed to the server. The
following example demonstrate passing an array using the helper methods in the RestClientUtils class.
var arrayCollection:ArrayCollection = new ArrayCollection(["abc","def"]);var result:RestResultRestComponentHelper.executeMethod("/some/Component","aMethod", [RestClientUtils.convertIListToMultivalue(arrayCollection,"java.util.ArrayList", "java.lang.String", RestConstants.JSON, session)], null, session, handleResult, handleFault);
The following example, which calls executeMethod(), produces the same result as the previous example:
var result:RestResultRestComponentHelper.executeMethod("/some/Component","aMethod", ["java.util.ArrayList:java.lang.String:[\"abc\",\"def\"]"], null,session, handleResult, handleFault)
The following examples use the helper methods in the RestClientUtils class.
12 Calling Methods 119
var result:RestResultRestComponentHelper.executeMethod("/some/Component", "aMethod", [RestClientUtils.convertArrayToMultivalue(["abc","def"],"java.util.HashSet", "java.lang.String", RestConstants.JSON, session)], null, session, handleResult, handleFault)
var obj:Object = new Object();obj["abc"] = 123;obj["def"] = 456;
var result:RestResultRestComponentHelper.executeMethod("/some/Component","aMethod", [RestClientUtils.convertObjectToMultivalue(obj, "java.util.HashMap","java.lang.String", "java.lang.Integer", RestConstants.JSON, session)], null, session, handleResult, handleFault)
13 Working with Repository Items 121
13 Working with Repository Items
This section provides instructions for ATG platform REST Web Services operations involving repositories.
A repository item is a JavaBean component that implements atg.repository.RepositoryItem or one of its
sub-interfaces, and corresponds to the smallest uniquely identifiable entity in the underlying data store. Each
repository item is composed of named properties that store the item’s data—for example, id, firstName, and
lastName.
About Output Format
All RestRepositoryHelper methods return results in the format that is configured as the default on the server
(JSON or XML). To override the default for a specific method, add the atg-rest-output parameter to the
pParams argument with a suitable value (“xml”, “json”, or the identifier for an appropriate output customizer).
For more information, refer to the Input and Output Formats (page 125) section.
About Repository Security
The ATG Platform REST Web Services module does not provide functionality for securing repository items All
ATG repository security is handled by the ATG secured repository system, which works in conjunction with the
ATG Security System to provide fine-grained access control to repository item descriptors, individual repository
items, and even individual properties. For more information, refer to the ATG Repository Guide
Getting Repository Items
The getItem() method of the RestRepositoryHelper class returns a data stream that contains all the
property values of a repository item.
The following code sample returns an array of URLs. Issuing a request using the
RestSession.createHttpRequest() method returns the property values of the requested item.
RestResult result = RestRepositoryHelper.getItem("/atg/commerce/catalog/ProductCatalog", "product",
122 13 Working with Repository Items
productId, params, session)
The getItems() method retrieves multiple repository items of the same type in a single call. The following
code sample returns an array of URLs:
RestResult result = RestRepositoryHelper.getItems("/atg/commerce/catalog/ProductCatalog", "product",params, session)
When a getItems() call returns many items, you can control the number of items returned with the atg-
rest-index and atg-rest-count parameters. The atg-rest-index parameter tells the server which item to
return first. The atg-rest-count parameter tells the server how many items past the index item to return.
In the following code sample, the first query, with an index of 0 and a count of 10, retrieves 10 items at a time.
The next query has an index of 10 and a count of 10, third, index of 20 and count of 10, and so on.
Map<String,String> params = new HashMap<String,String>();params.put(RestConstants.COUNT, 10);params.put(RestConstants.INDEX, 0);RestResult result = RestRepositoryHelper.getItems("/atg/commerce/catalog/ProductCatalog", "product",params, session);
params.put(RestConstants.INDEX, 10);
result = RestRepositoryHelper.getItems("/atg/commerce/catalog/ProductCatalog","product", params, session);
params.put(RestConstants.INDEX, 20);
result = RestRepositoryHelper.getItems("/atg/commerce/catalog/ProductCatalog","product", params, session);
Repository IDs
Each repository item has a unique identifier, called a repository ID. Depending on the repository’s configuration,
the repository ID might not be exposed as a property of the repository item. However, when a repository item is
returned with a Rest RepositoryHelper method, you can reliably retrieve its repositoryID by getting the value of
the repositoryId property.
Adding Repository Items
Create a repository item by calling the RestRepositoryHelper.createItem() method. You can supply a
repository ID for the newly created item or you can allow the server to generate a repository ID for you.
A createItem() call returns a data stream that contains all the properties of the created item. This is the same
data stream that is returned when you call RestRepositoryHelper.getItem().
The following code sample adds a repository item and allows the server to generate the repository ID:
13 Working with Repository Items 123
RestResult result = RestRepositoryHelper.createItem("/atg/commerce/catalog/ProductCatalog", "product",params, session);
The following code sample adds a repository item and specifies the value of myProductId-12345 as the
repository ID:
RestResult result = RestRepositoryHelper.createItem("/atg/commerce/catalog/ProductCatalog", "product","myProductId-12345", params, session);
Deleting Repository Items
Remove a repository item by calling the RestRepositoryHelper.removeItem() method. A removeItem()
call returns a data stream that contains the string true if the item was removed. If the item was not removed,
the call throws an exception.
The following sample removes a repository item:
RestResult result = RestRepositoryHelper.removeItem("/atg/commerce/catalog/ProductCatalog", "product","myProductId-12345", params, session);
Getting Repository Item Properties
The getPropertyValue() method of the RestRepositoryHelper class returns a data stream that contains
the value of the specified property.
The following sample gets the property value displayName from the product repository item.
RestResult result = RestRepositoryHelper.getPropertyValue("/atg/commerce/catalog/ProductCatalog","product", "prod12345", "displayName", params, session);
Setting Repository Item Properties
The setPropertyValue() method of the RestRepositoryHelper class sets the value of the specified
property.
124 13 Working with Repository Items
The following sample sets the property displayName to the string My Modified Display Name.
RestResult result = RestRepositoryHelper.setPropertyValue("/atg/commerce/catalog/ProductCatalog","product", "prod12345", "displayName", "My Modified Display Name", params,session);
Performing Queries for Repository Items
Performing queries for repository items using RQL is similar to retrieving them with getItems().,
but querying provides for more control over the items included in the results. Use the
RestRepositoryHelper.executeRQLQuery() method to execute and RQL query.
To request a range of items, use the atg-rest-index and atg-rest-count parameters with the
executeRQLQuery() method, just as you’d use them with getItems(). See Getting Repository Items (page
35) for more information.
In the following example, the INDEX and COUNT keywords in the RQL language are used instead of the “atg-rest-
index” and “atg-rest-count” parameters.
Map<String,String> params = new HashMap<String,String>();params.put(RestConstants.COUNT, 10);params.put(RestConstants.INDEX, 0);RestResult result = RestRepositoryHelper.executeRQLQuery("/atg/commerce/catalog/ProductCatalog","product", "age >= 30", params, session);params.put(RestConstants.INDEX, 10);result = RestRepositoryHelper.executeRQLQuery("/atg/commerce/catalog/ProductCatalog","product", "age >= 30", params, session);
params.put(RestConstants.INDEX, 20);result = RestRepositoryHelper.executeRQLQuery("/atg/commerce/catalog/ProductCatalog","product", "age >= 30", params, session);
14 Input and Output Formats 125
14 Input and Output Formats
ATG Platform REST Web Services supports JSON and XML input and output formats. JSON is the default format.
To change the default format, change the defaultOutputCustomizer and defaultInputCustomizer
properties of the /atg/rest/Configuration component so they point to the appropriate component.
For output, the property value should be set either to
/atg/rest/output/JSONOutputCustomizer
or
/atg/rest/output/XMLOutputCustomizer
For input, the property should point either to
/atg/rest/input/JSONInputCustomizer
or
/atg/rest/input/XMLInputCustomizer
Parsing Output
JSON Output
The following example shows JSON output. Notice how string values are surrounded by quotes, numerical
values have no quotes, multivalued elements are surrounded by brackets, and references to repository items
are URLs to the item referenced. Note that multivalued elements will be URLs also, but in this example, the
abcArray has been expanded.
{ "myClass": "class atg.rest.processor.MockObject", "size": 10, "abcArray":{ "type": int, "elements": [ 0, 1, 2,
126 14 Input and Output Formats
3 ]}, "product": "http://localhost/rest/repository/atg/commerce/catalog/ProductCatalog/product/prod12345",}
XML Output
The following example shows XML output for a bean that contains the following properties. Tags surround
each property value with the tag name being the property name. For multivalued properties, each entry is
surrounded by the element tag. Note that multivalued elements will be URLs also, but in this example, the
abcArray has been expanded.
Formatting Input
If you are using one of the client libraries that comes bundled with ATG Platform REST Web Services, you don’t
need to format input. The libraries manage input for you. If you do however, use REST without the client libraries,
then you will need to convert any input data to the correct format with a JSON or XML library.
The most important points to understand about the JSON or XML payload for a request are what is in the
payload and how the data is identified. The request parameters are always part of the payload and if the call is a
POST request/method call, then the method parameters are also passed in this format. Any request parameters
are simply added to the payload as name value pairs.
Notice that in both samples which follow, the values are passed as strings, even though they are numeric. Also
notice in the XML that the root tag uses parameters as the tag name.
The following sample shows JSON:
{ "atg-rest-index": "0", "atg-rest-count": "10"}
The following sample shows XML.
<parameters> <atg-rest-index>0</atg-rest-index> <atg-rest-count>10</atg-rest-count></parameters>
For method arguments, the name of each argument should be arg1, arg2, arg3 ... argN where N is the total
number of arguments in the method call. In the following samples, arg1 and arg2 are both passed as strings,
while arg3 is a repository item which is passed using a predefined format
repository path:item descriptor name:item id.
The following sample shows JSON:
14 Input and Output Formats 127
{ "atg-rest-index": "0", "atg-rest-count": "10" "arg1": "abc", "arg2": "55", "arg3": "/atg/commerce/catalog/ProductCatalog:product:prod12345"}
The following sample shows XML.
<parameters> <atg-rest-index>0</atg-rest-index> <atg-rest-count>10</atg-rest-count> <arg1>abc</arg1> <arg2>55</arg2> <arg3>/atg/commerce/catalog/ProductCatalog:product:prod12345</arg3></parameters>
Formatting Input with ActionScript
The option to use JSON or XML with ActionScript is available. In order to use JSON you will need to include the
Adobe corelib library. This library contains functionality to encode and decode JSON streams. In the example
below, the pEvent object is of type Event and is supplied by the Flash runtime when the handler method is
called. pEvent.target.data contains the response data stream. This stream is decoded into an Object. The
sample iterates through the properties constructing an object for each name/value pair and then adds it to an
ArrayCollection object.
var json:Object = JSON.decode(pEvent.target.data);for (var propName:String in json) arrayCollection.addItem({name: propName, value: json[propName]});
The following sample uses XML input. Note that you could also take advantage of the ECMAScript for XML
functionality once the XML object is created. The following sample does not use that approach, though it is an
option.
var xml:XML = new XML(pEvent.target.data);var xmlList:XMLList = pXML.elements();if (xmlList.length() == 0) xmlList = new XMLList(pXML); var count:int = 0;for each(var item:XML in xmlList) { if (item.name() != "element") array.addItem({name: item.name(), value: item.text()}); else if (item.hasComplexContent()) { var elementList:XMLList = item.child("element"); if (elementList != null && elementList.length() > 0) { var count2:int = 0; for each (var el:XML in elementList) array.addItem({name: count2++, value: el.text()}); } else array.addItem({name: item.key.text(), value: item.value.text()});
15 Property Filtering 129
15 Property Filtering
ATG Platform REST Web Services includes functionality that filters properties from output. You could use this
functionality to:
• Mark a certain property in a Nucleus component or repository item as hidden or not writable.
• Configure the system to override the default functionality of outputting all items and instead output only the
items defined in the filtering configuration file.
• Add your own custom properties for components or repository items and specify from where to get their
values.
An extension of the property filtering feature, called property aliasing, allows you to create virtual components
with properties that assemble values from a variety of sources.
The filtering configuration file is located at /atg/rest/filtering/filteringConfiguration.xml in the
config path. To customize it you will create that file in your own module and the server’s XML combination
functionality will combine all the filteringConfiguration.xml files.
The following sample makes one property hidden and another writable in a Nucleus component and a
repository item:
• property1 and repProperty1 are both hidden and will not be returned in the output whenever the
Nucleus component or that specific property is requested.
• property2 and repProperty2 cannot be changed by a REST request. (Note that the writable flag affects
only REST requests.)
<rest-filtering> <component name="/some/Component" default-include="true"> <property name="property1" hidden="true"/> <property name="property2" writable="false"/> </component>
<component name="/some/Repository" default-include="true"> <item-descriptor name="anItemDescriptorName"> <property name="repProperty1" hidden="true"/> <property name="repProperty2" writable="false"/> </item-descriptor> </component></rest-filtering>
The default-include attribute tells the server that it should return only the values specified inside this
component tag and ignore all other properties of the Nucleus component or repository item.
130 15 Property Filtering
The following sample adds additional properties which do not exist in the Nucleus component or repository
item. The sample also configures where the values for these “virtual” properties come from.
• The property called virtual1 does not exist in the /some/Component bean. Its value, specified by the
target attribute, is the value of property2 in the same object.
• Similarly, the repVirtual1 property returns the value of repProperty2 as its value.
• The target attribute also allows for subproperties to be specified, as the sample demonstrates for the
virtual2 and repVirtual2 properties. Note that the dot notation can be more than one level deep.
<rest-filtering> <component name="/some/Component" default-include="true"> <property name="property1" hidden="true"/> <property name="property2" writable="false"/> <property name="virtual1" target="property2"/> <property name="virtual2" target="property2.subproperty"/> </component>
<component name="/some/Repository" default-include="true"> <item-descriptor name="anItemDescriptorName"> <property name="repProperty1" hidden="true"/> <property name="repProperty2" writable="false"/> <property name="repVirtual1" target="repProperty2"/> <property name="repVirtual2" target="repProperty2.subproperty"/> </item-descriptor> </component></rest-filtering>
The next sample extends the previous one by adding a component attribute to the property tag and using
that in combination with the target tag. This demonstrates how the value of a property can come from another
Nucleus component. (Note that the component attribute can only reference a Nucleus component.) Dot
notation can be used in the target attribute when the component attribute is used.
<rest-filtering> <component name="/some/Component" default-include="true"> <property name="property1" hidden="true"/> <property name="property2" writable="false"/> <property name="virtual1" target="property2"/> <property name="virtual2" target="property2.subproperty"/> <property name="virtual3" component="/some/other/Component" target="aProperty"/> </component>
<component name="/some/Repository" default-include="true"> <item-descriptor name="anItemDescriptorName"> <property name="repProperty1" hidden="true"/> <property name="repProperty2" writable="false"/> <property name="repVirtual1" target="repProperty2"/> <property name="repVirtual2" target="repProperty2.subproperty"/> <property name="repVirtual3" component="/some/other/Component" target="aProperty"/> </item-descriptor> </component></rest-filtering>
Finally, if you need to write custom code to specify your value, then you must use the property-customizer
attribute, as shown in the following sample.
15 Property Filtering 131
<rest-filtering> <component name="/some/Component" default-include="true"> <property name="property1" hidden="true"/> <property name="property2" writable="false"/> <property name="virtual1" target="property2"/> <property name="virtual2" target="property2.subproperty"/> <property name="virtual3" component="/some/other/Component" target="aProperty"/> <property name="virtual4" property-customizer="some.class.Here"/> </component>
<component name="/some/Repository" default-include="true"> <item-descriptor name="anItemDescriptorName"> <property name="repProperty1" hidden="true"/> <property name="repProperty2" writable="false"/> <property name="repVirtual1" target="repProperty2"/> <property name="repVirtual2" target="repProperty2.subproperty"/> <property name="repVirtual3" component="/some/other/Component" target="aProperty"/> <property name="repVirtual4" property-customizer="some.class.Here"/> </item-descriptor> </component></rest-filtering>
When using the property-customizer attribute, the value should be the name of a class which implements
the atg.rest.filtering.RestPropertyCustomizer interface, shown below.
public Object getPropertyValue(String pPropertyName, Object pResource);
public void setPropertyValue(String pPropertyName, Object pValue, Object pResource);
Property Aliasing
An extension of the property filtering feature, called property aliasing, allows you to create virtual components
with properties that assemble values from a variety of sources.
The following sample specifies the name of a component which does not exist in the name attribute of the
component tag, thus creating a virtual component. When creating virtual components in this way, do not use
the item-descriptor tag. When this component is requested, the list of properties which is specified inside
the component tag will be rendered. When requesting this component, use only the property tag with the
component/target attributes or the property-customizer attribute, as the others do not provide value.
The value in creating virtual component is that it allows for data from a variety of sources to be gathered and
returned in a single request.
<rest-filtering> <component name="/some/nonexisting/Component"> <property name="proeprty1" component="/some/other/Component" target="aProperty"/> <property name="property2" property-customizer="some.class.Here"/> </component><rest-filtering>
16 Security 133
16 Security
The security functionality for ATG Platform REST Web Services allows security to be placed on multiple levels of
granularity for Nucleus components.
Before you read this chapter, you should have a thorough understanding of ATG user account security. For more
information, see Managing Access Control in the ATG Programming Guide.
The default configuration for ATG Platform REST Web Services is to not allow access to any components. This
means that you will need to configure security to be able to call methods or access properties on Nucleus
components.
Security on Nucleus components can be configured globally for all components, at the component level for all
properties and methods, at the property level, at the method level, and for entire Nucleus subtrees. The REST
security subsystem depends on the ATG security system and therefore uses ACLs which are similar to those
used to configure security in other parts of an ATG server. The personas can be users, organizations, or roles. The
valid rights which can be assigned to a personas are read, write, and execute. Read and write refer to Nucleus
properties and execute refers to Nucleus methods. To configure multiple personas, use a semicolon (;) character
to separate each access control entry (persona/rights).
The REST security configuration file is located at /atg/rest/security/restSecurityConfiguration.xml.
To add your own security configuration create a file at that location in the config directory of your module.
Note: The ATG Platform REST Web Services module does not provide functionality for securing repository
items All ATG repository security is handled by the ATG secured repository system, which works in conjunction
with the ATG Security System to provide fine-grained access control to repository item descriptors, individual
repository items, and even individual properties. For more information, see the ATG Repository Guide.
Global Security
To configure global security, use the default-acl tag. This tag defines which personas have access to Nucleus
components. In the following example, all users who are assigned the restUser role have read and write
access to all Nucleus properties and execute access for all methods on Nucleus components. The default-
acl tag is optional. This example assumes that a role called restUser has already been created in the profile
repository.
<rest-security> <default-acl value="Profile$role$restUser:read,write,execute"/> </rest-security>
134 16 Security
Component Security
To configure security on a specific component, use the resource tag. This tag, along with the component
attribute, allows you to define which users have access to the specified component. You could disable security
entirely for the specified component by using the optional secure attribute.
In the following example, the /some/Component component is configured so that only the user whose login
is admin has full access to it; users with the restUser role only have read access. In addition, the /some/
other/Component component is configured to disable security. This means that all users have full access to all
properties and methods of that component.
<rest-security> <default-acl value="Profile$role$restUser:read,write,execute"/>
<resource component="/some/Component"> <default-acl value="Profile$login$admin:read,write,execute;Profile$role$restUser:read"/> </resource>
<resource component="/some/other/Component" secure="false"/></rest-security>
Property and Method Security
To configure security on a component property or method, add a property or method tag within the resource
tag. The property and method tags allow you to specify at the property or method level to which users have
access for the specified property or method.
In the following example, property1 and methodA in /some/Component can be accessed only by the admin
user. property2 and methodB can be accessed by anyone because security has been disabled on it.
<rest-security> <default-acl>Profile$role$restUser:read,write,execute"</default-acl>
<resource component="/some/Component"> <default-acl value="Profile$login$admin:read,write,execute;Profile$role$restUser:read"/>
<property name="property1"> <acl value="Profile$login$admin:read,write"/> </property>
<property name="property2" secure="false"/>
<method name="methodA"> <acl value="Profile$login$admin:execute"/> </property>
<method name="methodB" secure="false"/> </resource>
16 Security 135
<resource component="/some/other/Component" secure="false"/></rest-security>
Methods which are overloaded and have different security requirements require a signature attribute,
available on the method tag. This attribute allows for a Java method signature that uniquely identifies the
method.
Securing Groups of Components
The ATG Platform REST Web Services provide the ability to secure groups of components within the same
Nucleus subtree. This is accomplished by using the * wildcard character. Note that * is the only wildcard
character allowed.
The following example sets the ACL for all components within the /atg/commerce subtree to be accessible only
by users with the restCommerceUser role.
<rest-security> <default-acl>Profile$role$restUser:read,write,execute"</default-acl>
<resource component="/atg/commerce/*"> <default-acl value="Profile$role$restCommerceUser:read,write,execute"/> </resource></rest-security>
17 Control Parameters 137
17 Control Parameters
This chapter includes the complete list of parameters that can be supplied to a request to modify its behavior.
Parameter Description
atg-rest-depth The number of references to traverse when rendering output. By default it is 0
which causes only the top level object to be returned.
atg-rest-output Allows the request to override the server default’s output format.
Can be either “json” or “xml”
atg-rest-input Allows the request to override the server default’s input format.
Can be either “json” or “xml”
atg-rest-index For requests which return an array or ordered list, adding this parameter with
an integer value allows the caller to specify from which entry to begin the
output. Used with atg-rest-count.
atg-rest-count For requests which return an array or ordered list, adding this parameter with
an integer value allows the caller to specify the number of elements to return.
Used with atg-rest-index.
atg-rest-rql When making an RQL query request, this parameter’s string value contains
the RQL query string.
atg-rest-transient When creating a repository item, adding this parameter with a value of “true”
tells the server to create a transient item.
atg-rest-method When calling an overloaded method, this parameter’s string value should
specify the Java method signature.
This parameter is needed only if two or more instances of the overloaded
method have the same number of arguments.
atg-rest-http-method For client applications which do not support the PUT or DELETE HTTP
method types, this string parameter allows the caller to issue a POST request,
specifying either PUT or DELETE for this parameter. The server will treat the
request using the method specified in this parameter.
138 17 Control Parameters
Parameter Description
atg-rest-simple-
response-codes
Tells the server to return OK (200) for success rather than CREATED (201) or
GONE (410).
18 HTTP Status Codes 139
18 HTTP Status Codes
The ATG Platform REST Web Services return an appropriate HTTP Status code for each request.
200 (OK) - The Request was successful. For a GET request, the response contains an entity corresponding to the
requested resource. In a POST request the response will contain an entity describing or containing the result of
the action.
201 (Created) - Returned only for POST requests that create repository items. The request was successful and the
repository item was created.
400 (Bad Request) - The request could not be completed because the request URL and/or parameters were
improperly formatted.
401 (Unauthorized) - user session does not have the proper security credentials to execute the method,
property, or access the repository for the requested resource.
403 (Forbidden) – The specified property has been configured as not writable via the filtering configuration.
404 (Not Found) - The request could not be completed because it was made for a resource which does not exist.
410 (Gone) - Returned only for DELETE requests that remove repository items. The request was successful and
the repository item was deleted.
500 (Internal server error) - The request could not be completed because an unexpected exception occurred.
Error Messages
If a message (for example, an exception) needs to be sent with the response, it will be added through the
HttpServletResponse.sendError(int pStatus, String pMessage) call.
Index 141
Index
Symbols.NET clients
ATGWS.dll, 58
before calling Web services, 55
calling Web services, 53
client stubs, 54
security, 53
session sharing, 42, 54
transactions, 54
Web service call examples, 57, 57
Aabout ATG Web services, 41, 53
accessing ATG Web services from .NET clients, 53
accessing ATG Web services from Java clients, 41
ActionScript client library, 111
add-item tag, 88
addItem operations, 79
AddService, 37
data validation, 37
ATG Web services, 1, 15
atg.adapter.integrations.ChangedPropertyBean, 75
atg.adapter.integrations.IntegrationRepository, 72
atg.adapter.integrations.IntegrationRepositoryItem, 75
atg.adapter.integrations.IntegrationRepositoryItemDescriptor,
75
atg.adapter.integrations.IntegrationRepositoryView , 76
Atg.DotNet.WebService API, 58
Atg.DotNet.WebService.ComplexType, 62
Atg.DotNet.WebService.NoSuchPropertyException, 62
Atg.DotNet.WebService.Property, 61
Atg.DotNet.WebService.RepositoryItem, 60
Atg.DotNet.WebService.RepositoryItemRef, 61
Atg.DotNet.WebService.RepositoryItemSerializationException,
63
atg.integrations.BaseCommand, 95
atg.integrations.BaseCommandHandler, 95
atg.integrations.Command interface, 93
atg.integrations.CommandHandler interface, 94
atg.integrations.CommandResults, 95
atg.integrations.MapRPCDroplet, 96
atg.repository.databinding.MappingRepositoryItem, 75
atg.repository.RepositoryService, 25
atg.repository.xml.AddService, 37
atg.repository.xml.GetService, 35
atg.repository.xml.RemoveService, 40
atg.repository.xml.UpdateService, 38
atg.repository.xml.XMLSchemaManager, 33
ATGWS.dll
client stubs for .NET, 54, 58
deserializing RepositoryItems, 54
installing, 55
serializing RepositoryItems, 54
Axis
calling Web services using, 45
Cclient libraries
REST, 103
client stubs for .NET, 54
client stubs for Java clients (see static Web service calls)
command operations
addItem, 79
executeQuery, 77
getItem, 78
Integration Repository, 77
removeItem, 80
updateItem, 78
CommandHandlers, 94
CommandResults, 95
commands, 94
executing, 94
executing in pages, 96
invoking, 94
CookieContainer, 42, 42, 43, 54
.Net client example, 57
Java client example, 47, 47
custom Web services, 5
Ddata binding
repository to XML (see repository to XML data binding)
data validation, 37, 38
definition files
Integration Repository, 70, 85
derived properties
updating, 79
derived-properties tag, 88
deserializing content on the client side, 48, 58
dot Net clients (see .NET clients)
DTDs
Integration Repository, 89
repository to XML mapping files, 28
142 Index
dynamic Web service calls, 47
distinction from static calls, 45
limitations, 45
Dynamo Administration UI
Web service creation wizard, 7, 19
Web service registry, 16
Web service security manager, 15
EexecuteQuery operations, 77
GgenerateXMLSchema utility, 32
get-item tag, 87
getItem operations, 78
GetService, 35
Iinput format
REST, 125
Installing ATGWS.dll, 55
Integration Data repository, 80
cleaning up, 81
Integration Repository, 67
APIs, 71
architecture, 67
command operations, 77
definition files, 70, 85
DTD, 89
examples, 82
operations, 67
persistent cache, 80
queries, 76
setting up, 70
IntegrationRepository component, 71, 72
IntegrationRepositoryView, 67
item-descriptor tag, 85
JJava client library
REST, 103
Java clients
before calling Web services, 43
calling Web services, 41
CookieContainer, 42, 43, 47, 47
deserializing content, 48
dynamic Web service calls, 47
security, 41
serializing content, 48
static Web service calls, 46, 47
transactions, 42
two ways to call Web services, 45
JAX-RPC, 6
deployment descriptor, 13
mapping file, 13
JMS Web services, 19
MessageImporter component, 19
Patch Bay configuration, 20
JSON output, 125
Mmapping files
DTD, 28
example, 29
repository to XML data binding, 28
MappingRepositoryItem, 75
MessageImporter component, 19
methods
calling with REST, 115
Nnamespaces
XML Schema, 36
Nucleus componants
REST, 113
Nucleus component Web services, 8
Ooperations
repository items, 67
output format
REST, 121, 125
PPatch Bay configuration for JMS Web services, 20
persistent cache (see Integration Data repository)
property aliasing, 131
property filtering, 129
propertyElementNameSeparator, 34
Qqueries
executeQuery operation, 77
Integration Repository, 76
query tag, 87
RRemote Procedure Calls, 93
APIs, 93
exception handling, 96
remove-item tag, 88
removeItem operations, 80
RemoveService, 40
removing repository items, 40
Index 143
repository IDs
REST, 122
repository items
generating from XML documents, 37
REST Web Services, 121
transforming into XML documents, 35
repository to XML data binding, 27
mapping files, 28
XML Schemas, 32
repository to XML mapping files
DTD, 28
example, 29
repository Web services, 23
limitations, 24
Repository XML schema
generating, 50
mapping file, 49
RepositoryItems
deserializing, 48, 58
serializing, 48, 58
Web service calls from Java clients, 42, 54
XML schema for Web service calls, 46
RepositoryService class, 25
requests
REST, 103
REST
add repository items, 122
calling methods, 115
client libraries, 103
delete repository items, 123
get repository items, 121
input and output format, 125
Nucleus componants, 113
output format, 121
property aliasing, 131
property filtering, 129
security, 133
REST Web Services, 99
repository items, 121
RPCs (see Remote Procedure Calls)
SScenario Manager
receiving messages from JMS Web services, 21
SchemaManager component, 33
security
REST, 133
Serializing content on the client side, 48, 58
service endpoint interface, 9
service interface class, 9
session sharing
example, 47, 47, 57
sessions
sharing (.NET clients), 42, 54
static Web service calls, 46
creating and compiling stubs, 46
creating and compiling the client, 47
distinction from dynamic calls, 45
WSDL, 46, 46
stubs (see client stubs) (see client stubs for .NET)
UupdateItem operations, 78
derived properties, 79
UpdateService, 38
data validation, 38
updating repository items
from XML documents, 38
Vvalidating data
AddService, 37
UpdateService, 38
WWeb service security, 13
NucleusSecurityManager, 14
NucleusSecurityRepository, 14
Web services
Administration UI, 7, 19, 23
ATG Web services, 1, 15
before calling from .NET, 55
before calling from Java clients, 43
calling from .NET clients, 53, 56
calling from Java clients, 41, 45, 47
client stubs for .NET, 54
custom Web services, 5
deploying, 15
generating, 6
infrastructure, 1
JMS messages, 19
limitations, 6
managing, 16
naming restrictions, 9
Nucleus component methods, 8
overview, 5
repository items, 23
runtime classes, 13
security, 6, 41, 42, 42, 53, 54, 54, 54
transactions, 42, 54
wizard, 7, 19
web.xml files, 11
WSDL documents, 10
144 Index
XXML documents
generating from repository items, 35
transforming into repository items, 37
updating repository items, 38
XML output, 126
XML SchemaManager component, 33
XML Schemas
for Web services, 48
generation utility, 32
itemRef attribute, 34
namespace, 36
references to other repository items, 34
repository to XML data binding, 32