Professional Documents
Culture Documents
Version 2007.1
Web Services and Integration Framework Guide
ATG
One Main Street
Cambridge, MA 02142
www.atg.com
Copyright
Copyright 1998-2007 Art Technology Group, Inc. All rights reserved.
This publication may not, in whole or in part, be copied, photocopied, translated, or reduced to any electronic medium or machine-readable
form for commercial use without prior consent, in writing, from Art Technology Group, Inc. (ATG) ATG does authorize you to copy
documents published by ATG on the World Wide Web for non-commercial uses within your organization only. In consideration of this
authorization, you agree that any copy of these documents which you make shall retain all copyright and other proprietary notices
contained herein.
Trademarks
ATG, Art Technology Group, and DYNAMO are registered trademarks of Art Technology Group, Inc.
ATG Wisdom, ATG Dynamo Application Server, ATG Adaptive Scenario Engine, ATG Scenario Personalization, ATG Portal, ATG Commerce,
ATG Content Administration, ATG Data Anywhere Architecture, ATG Search, ATG Response Management, ATG Merchandising, ATG
Knowledge, ATG Self Service, ATG Commerce Assist, ATG Advisor, ATG Forum and ATG Business Control Center are trademarks of Art
Technology Group, Inc.
Microsoft, Windows and Word are the trademarks or registered trademarks of Microsoft Corporation in the United States and other countries.
IBM, AIX, and MQ-Series are the trademarks or registered trademarks of IBM Corporation in the United States and other countries. Oracle is a
registered trademark, and other Oracle product names, service names; slogans or logos referenced in this document are trademarks or
registered trademarks of Oracle Corporation. Adobe Acrobat Reader is a registered trademark of Adobe. CORBA is a trademark of the OMG
(Object Management Group). Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems,
Inc. in the United States and other countries. Primus, and its respective logo, and Primus Knowledge Solutions, are trademarks, registered
trademarks, or service marks of Primus.
This product includes software developed by the Apache Software Foundation (http://www.apache.org/).
EditLive Authoring Software Copyright 2004 Ephox Corporation. All rights reserved. Includes code licensed from RSA Security, Inc.. Some
portions licensed from IBM are available at http://oss.software.ibm.com/icu4j/. Includes software developed by the Apache Software
Foundation (http://www.apache.org/). Contains spell checking software from Wintertree Software Inc.. The Sentry Spell Checker Engine
2000 Wintertree Software Inc..
All other product names, service marks, and trademarks mentioned herein are trademarks of their respective owners. This publication may
not, in whole or in part, be copied, photocopied, translated, or reduced to any electronic medium or machine-readable form for commercial
use without prior consent, in writing, from Art Technology Group (ATG), Inc. ATG does authorize you to copy documents published by ATG
on the World Wide Web for non-commercial uses within your organization only. In consideration of this authorization, you agree that any
copy of these documents which you make shall retain all copyright and other proprietary notices contained herein.
No Warranty
This documentation is provided as is without warranty of any kind, either expressed or implied, including, but not limited to, the implied
warranties of merchantability, fitness for a particular purpose, or non-infringement.
The contents of this publication could include technical inaccuracies or typographical errors. Changes are periodically added to the
information herein; these changes will be incorporated in the new editions of the publication. ATG may make improvements and/or changes
in the publication and/or product(s) described in the publication at any time without notice.
Limitation of Liability
In no event will ATG be liable for direct, indirect, special, incidental, economic, cover, or consequential damages arising out of the use of or
inability to use this documentation even if advised of the possibility of such damages. Some states do not allow the exclusion or limitation of
implied warranties or limitation of liability for incidental or consequential damages, so the above limitation or exclusion may not apply to
you.
ATG One Main Street Cambridge MA 02142
617.386.1000 phone 617.386.1111 fax www.atg.com
Contents
7
8
11
11
12
12
12
12
13
13
15
15
16
16
17
20
20
20
20
21
22
22
23
25
27
27
28
28
31
31
32
33
34
iii
Contents
37
37
38
41
43
44
45
45
45
46
48
49
51
53
53
53
54
54
55
55
56
56
57
59
60
61
61
63
63
63
64
64
64
64
65
65
66
66
66
67
68
70
71
72
iv
Contents
72
73
73
74
75
75
Integration Repository
77
Architecture
Integration Approaches
Remote Only
Remote then Local
Local then Remote
Local Only
Setting Up an Integration Repository
Defining an Integration Repository
Integration Repository APIs
IntegrationRepository
IntegrationRepositoryItemDescriptor
IntegrationRepositoryItem
ChangedPropertyBean
atg.repository.databinding.MappingRepositoryItem
IntegrationRepositoryView
Command Operations
executeQuery
getItem
updateItem
addItem
removeItem
Mapping
Persistent Caching
Cleaning up the Persistent Cache
Configuration Examples
Configuring the Remote-Only Model
Configuring the Remote-then-Local Model
Configuring the Local-then-Remote Model
Integration Repository Definition File
integration-repository-template tag
header tag
item-descriptor tag
item-descriptor Child Tags
integration-repository Document Type Definition
77
78
78
79
79
80
80
81
82
83
85
86
86
86
86
88
88
89
89
90
91
91
92
93
93
93
95
96
96
97
97
97
98
101
105
105
v
Contents
Command Interface
CommandHandler Interface
CommandResult Class
Implementing the RPC API
Exception Handling
Executing Commands in Pages
Index
105
106
107
107
108
108
111
vi
Contents
A 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 employees profile in both
systems. Ideally, youd 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 employees 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
youre 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
Creating JMS Web Services
Creating Repository Web Services
Repository to XML Data Binding
Accessing ATG Web Services from Java Clients
Accessing ATG Web Services from .NET Clients
7
Part I: Creating and Using Web Services in the ATG Platform
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
Generic Repository
Services
- getRepositoryItem
User Session
Messaging
- sendPageVisit
- performRQLQuery
- performRQLCountQuery
loginUser
logoutUser
getProfileId
setLocale
setContactInfo
setPassword
getProfile
createUser
updateUser
getPasswordHashKey
getPasswordHashAlgorithm
canClientEncryptPasswords
executeRepositoryTargeter
- sendClickThrough
8
Part I: Creating and Using Web Services in the ATG Platform
DCS.WebServices
Order
Pricing
- calculateOrderPrice
- calculateOrderPriceSummary
- calculateItemPriceSummary
Promotions
Inventory
- getInventory
createOrderFromXML
submitOrderWithReprice
cancelOrder
getOrderStatus
getOrderAsXML
getOrdersAsXML
getOrderStatus
getCurrentOrderId
addItemToOrder
addItemToShippingGroup
createOrder
createOrderForUser
removeItemFromOrder
setItemQuantity
addCreditCardToOrder
addShippingAddressOrder
removePaymentGroupFromOrder
removeCreditCardFromOrder
removeShippingGroupFromOrder
moveItemBetweenShippingGroups
removeItemQuantityFromShippingGroup
setOrderAmountToPaymenGroup
getDefaultPaymentGroupId
getDefaultShippingGroupId
grantPromotion
revokePromotion
claimCoupon
getPromotionsAsXML
- getInventoryStatus
- setStockLevel
- setStockLevels
Catalog
getProductXMLById
getProductXMLByDescription
getProductXMLByRQL
getProductSkusXML
catalogItemViewed
Profile
setDefaultShippingAddress
setDefaultBillingAddress
setDefaultCreditCard
getDefaultShippingAddress
getDefaultBillingAddress
getDefaultCreditCard
9
Part I: Creating and Using Web Services in the ATG Platform
10
Part I: Creating and Using Web Services in the ATG Platform
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:
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 chapter. For
information specific to Web services that perform repository operations, see the Creating Repository Web
Services chapter.
This chapter includes the following sections:
Overview of ATG Web Services Support
Web Service Creation Wizard
Anatomy of a Web Service
Web Service Security
Deploying Web Services
Managing Web Services
JAX-RPC
Limitations
11
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 Suns 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.
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
12
1 - Creating Custom Web Services
either rewrite the method to use a primitive instead (if the methods class is your own
custom code), or else subclass the methods 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 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.
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.
These steps are described in more detail in the Anatomy of a Web Service 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.
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.
13
1 - Creating Custom Web Services
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.
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).
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.
14
1 - Creating Custom Web Services
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 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.
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 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 youll 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.
15
1 - Creating Custom Web Services
WSDL document
web.xml file
runtime classes
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.
WSDL Document
Web Services Description Language (WSDL) is an XML language for describing Web services in a platformindependent way. A WSDL document describes a Web services 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:
At runtime, it is used by Web service clients to look up the semantics of the SOAP
messages to send to invoke the service.
16
1 - Creating Custom Web Services
When the Web services 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.
2.
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:
17
1 - Creating Custom Web Services
<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=GetOrderStatusSEIService
port0.tie=webservices.GetOrderStatusSEI_Tie
wsdl.transform=true
port0.name=getOrderStatus
portcount=1
wsdl.location=WEB-INF/getOrderStatus.wsdl
port0.servant=webservices.GetOrderStatusSEIImpl
port0.wsdl.targetNamespace=http\://www.atg.com/webservices
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.
For example:
<filter>
<filter-name>WSDLImportFilter</filter-name>
18
1 - Creating Custom Web Services
<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>
<servlet>
<servlet-name>WebServiceRegistrar</servlet-name>
<display-name>WebServiceRegistrar</display-name>
<description>ATG WebServiceRegistrar for registering servlet
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.
19
1 - Creating Custom Web Services
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
20
1 - Creating Custom 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
ATGs 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:
associated with the Web service to apply the corresponding security policy and ACL,
to determine whether to grant or deny access.
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 services security configuration, the name of the Nucleus component and method exposed by the
service, and a Map containing the methods 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.
21
1 - Creating Custom Web Services
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.
The Web Services Administration interface provides an easy way to add new security configurations to
this repository. See the next section for details.
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.
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
22
1 - Creating Custom Web Services
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.
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.
23
1 - Creating Custom Web Services
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
applications name. For example, if you click on the link for the Pricing application, the Service Info looks
like this:
24
1 - Creating Custom Web Services
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 section.
25
1 - Creating Custom Web Services
26
1 - Creating Custom 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 email 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.
27
2 - Creating JMS Web Services
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 clients 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 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 chapter.
<message-source>
<nucleus-name>
28
2 - Creating JMS Web Services
/atg/dynamo/messaging/MessageImporter
</nucleus-name>
<output-port>
<port-name>
IndividualEvents
</port-name>
<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.
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.
29
2 - Creating JMS Web Services
30
2 - Creating JMS 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 section of the Creating Custom
Web Services 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.
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.
31
3 - Creating Repository Web Services
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 for
more information.
Click the name of the method you want to expose in your Web service.
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:
If you choose the last option, the wizard then prompts you to select a security
configuration. See the Creating Custom Web Services chapter for information about
security configurations for Web services.
8.
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
<ATG2007.1dir>/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 in the
Creating Web Services chapter.
32
3 - 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.
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.
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.
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.
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.
33
3 - Creating Repository Web Services
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 dont 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 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
mappingManager
atg.repository.xml.
ItemDescriptorMappingManager
class.
xmlGetService
atg.repository.xml.
GetService
xmlAddService
atg.repository.xml.
AddService
xmlUpdateService
atg.repository.xml.
UpdateService
34
3 - Creating Repository Web Services
For information about the XML service properties, see Repository Operations in the Repository to XML Data
Binding chapter.
35
3 - Creating Repository Web Services
36
3 - Creating Repository Web Services
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)
Mapping files control which data is exchanged between system, and which data is
omitted.
37
4 - Repository to XML Data Binding
XML Schemas describe the structure of the data, and can be used to validate XML
instance documents.
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.
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:
38
4 - Repository to XML Data Binding
<!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">
39
4 - Repository to XML Data Binding
</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 itemdescriptor 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">
The default-include attribute specifies whether the items properties should be included or excluded
by default. This value can be overridden for individual properties. In this mapping file, various scenariorelated properties are excluded:
<property
<property
<property
<property
name="slotInstances" include="false"/>
name="scenarioInstances" include="false"/>
name="mailings" include="false"/>
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"/>
40
4 - Repository to XML Data Binding
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:
Property Name
Type
Description
repositoryPath
java.lang.String
is a read-only property
repository
atg.repository.Repository
itemDescriptorMapping
java.util.Map
Here is an example properties file for an ItemDescriptorMapping that supports the profile repository:
$class=atg.repository.xml.ItemDescriptorMapping
repository=/atg/userprofiling/ProfileAdapterRepository
41
4 - Repository to XML Data Binding
itemDescriptorMapping=\
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 dont 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:
Property Name
Type
Description
itemDescriptorMappings
atg.repository.xml.
ItemDescriptorMapping[]
An array of
ItemDescriptorMapping
$class=atg.repository.xml.ItemDescriptorMappingManager
itemDescriptorMappings=\
/atg/userprofiling/UserProfileItemMapping,\
/atg/userprofiling/ContactInfoItemMapping
42
4 - Repository to XML Data Binding
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.
-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
-schemaGenerator
43
4 - Repository to XML Data Binding
-m
-help
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 .
Notice that only the name of the mapping file is specified, not the entire pathname. The Schema
Managers mappingFileDirectories property points to the directories where the mapping file should
be stored.
44
4 - Repository to XML Data Binding
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>
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
45
4 - Repository to XML Data Binding
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.
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"
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>
46
4 - Repository to XML Data Binding
<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>sandy@example.com</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
(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
47
4 - Repository to XML Data Binding
important if youre 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.
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.
48
4 - Repository to XML Data Binding
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.
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.
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.
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>sandy@example.com</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):
49
4 - Repository to XML Data Binding
Note that UpdateService determines the repository and item type from the namespace of the instance
document. For more information, see Namespaces in the Getting Repository Items section.
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 a user 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 items 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"/>
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.
50
4 - Repository to XML Data Binding
repositoryId
The repositoryId attribute of an item can be used as a special match property. If the repositoryId
String 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"
xsi:schemaLocation="http://www.atg.com/ns/UserProfiles/user
UserProfiles+user.xsd " ID="user747" repositoryId="user707">
<user:user.emailAddress>sandy@example.com</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.
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);
51
4 - Repository to XML Data Binding
52
4 - Repository to XML Data Binding
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. Java clients are able to contact those
Web services through a carefully constructed call thats built in Java, 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 JAXRPC 1.0 and SOAP 1.1 specifications. This chapter assumes that you will use Apache Axis 1.1 to create your
Web service call. Although you are not required to use Axis 1.1, you are strongly encouraged to do so. The
ATG platform supplements the Axis offering with an extension that provides support for session sharing.
See Sharing Sessions for more information.
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 your Axis documentation for comprehensive instructions.
To access an ATG Web service, you need to be familiar with the following topics:
About ATG Web Services
Before You Begin
Calling ATG Web Services
Creating a Serializer and Deserializer
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. All subsequent Web service calls
in that session are associated with that identity and related role.
53
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
ATGs implementation of sessions and session sharing provides considerable flexibility to Java clients. To
understand how, you need to know a little about ATG Web services.
There are two limitations that affect the ATG implementation:
The JAX-RPC specification restricts a session to one or more calls per Web service
endpoint. The Axis implementation obeys this restriction.
This means that each session is comprised of calls made to just one method on one Web service. Had ATG
not extended the JAX-RPC concept of sessions to include session sharing, Web services would need to be
entirely self-reliant: related Web services could not execute in succession.
Consider Web service security. Currently, the loginUser Web service determines the security role of the
client and allows that to govern the content that the other Web services within that session are able to
access. If there were no session sharing, there could be no way to provide security, given that each Web
service can have only one method.
ATG provides the ability for Web services to share sessions by extending the Axis offering to include a
org.apache.axis.cookies.CookieContainer class. A CookieContainer enables HTTP cookies to be
54
5 - Accessing ATG Web Services from Java Clients
The first Web service called returns a response with a set-cookie header holding a new session ID because
no active session IDs exist in the CookieContainer. That new session ID is then saved to the
CookieContainer. For each subsequent call, the resource is again analyzed and when its determined
that maintain sessions is true, the CookieContainer provides the active session ID to the cookie in the
request.
In short, to make Web services able to share sessions, two things need to happen:
1.
The Web service call must be configured to instantiate the CookieContainer and
permit session sharing. For instructions, see the sections for creating Web service calls.
2.
The Web service itself must support sessions. When you create custom Web services,
you are given the option to allow sessions.
RepositoryItems
A RepositoryItem is a specialized JavaBean called a Dynamic Bean that produces basic get and set
methods for the fields you define in it. Many complex items are stored by the ATG platform as
RepositoryItems. When your Web services access RepositoryItems, you need to provide a serializer
and/or deserializer so the RepositoryItem content can be interpreted by non-ATG systems.
The following Web Services transmit content thats natively stored as RepositoryItems:
getProfile
getRepositoryItem
performRQLQuery
The ATG platform includes several tools for working with RepositoryItems. To make a client able to
serialize/deserialize RepositoryItems, you need to translate the RepositoryItem class into a language
thats native to your client. See Creating a Serializer and Deserializer for more information.
55
5 - Accessing ATG Web Services from Java Clients
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.
2.
Install Apache Axis 1.1 with the ATG libraries. See Installing Axis for instructions.
Installing Axis
Although you can use any Java client you like, you are recommended to use Axis 1.1 because, in addition
to its exceptional tools, the ATG platform includes an extension that alleviates the session management
restrictions in Axis that are mandated by the JAX-RPC specification.
Users who have installed Axis previously, can skip steps one and two. Keep in mind that when you install
the ATG extension, you overwrite your current axis.jar file so if youve modified it, your work will be
overwritten.
To install Axis and the ATG extension:
1.
2.
3.
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 its primitive, complex, object, or nonstandard. 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):
56
5 - Accessing ATG Web Services from Java Clients
Boolean
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.
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 supportive
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 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 below.
4.
57
5 - Accessing ATG Web Services from Java Clients
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.
Its 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.
Create a Web service client that includes the following standard code:
LoginUserSEIService loginService = new LoginUserSEIServiceLocator();
LoginUserSEI loginStub = loginService.getLoginUserSEIPort();
String userId = loginStub.loginUser("bhavern", "xyo8bnif", false);
2.
To enable session sharing for this Web service call, include the following information
in your client stub:
org.apache.axis.cookies.CookieContainer cookie = new CookieContainer();
((loginUser)loginUser).setMaintainSession(true);
((loginStub)loginService).setCookieContainer(cookie);
58
5 - Accessing ATG Web Services from Java Clients
This code instantiates the CookieContainer, saves the Web service calls session ID
to the CookieContainer when an ID exists, and permits the CookieContainer to
share the Web service calls session ID with other calls.
3.
2.
To provide session sharing capabilities, you need to add the following code:
org.apache.axis.cookies.CookieContainer cookie = new CookieContainer();
call.setMaintainSession(true);
call.setCookieContainer(cookie);
59
5 - Accessing ATG Web Services from Java Clients
3.
4.
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
2.
60
5 - Accessing ATG Web Services from Java Clients
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 for instructions.
2.
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.
2.
choosing.
61
5 - Accessing ATG Web Services from Java Clients
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 schema for order, remember to do so
while the same modules are running as will run when your Web service calls that item descriptor.
62
5 - Accessing ATG Web Services from Java 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. .NET clients are able to contact those Web
services through a carefully constructed call thats 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
Before You Begin
Calling ATG Web Services
Using the Atg.DotNet.WebService API to Serialize and Deserialize RepositoryItems
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. 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.
63
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
To make Web services able to share sessions on .NET, two things need to happen:
1.
The Web service client needs to allow a session to be shared across certain 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.
2.
The Web services themselves must support sessions. When you create custom Web
services, you are given the option to allow 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 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.
getProfile
getRepositoryItem
performRQLQuery
64
6 - Accessing ATG Web Services from .NET Clients
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. You can find this API in ATGWS.dll, which you need to install in order to
access them. See Installing ATGWS.dll.
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.
2.
Install Apache Axis 1.1 with the ATG libraries. See Installing Axis for instructions.
3.
Install Internet Information Service (IIS) and then Active Server Page.Net (ASP.NET) and
VisualStudio.NET (VS.NET).
4.
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.
2.
65
6 - Accessing ATG Web Services from .NET Clients
2.
Create instances of the client stubs and use them in your Web service call.
Assemble your application. Make sure you include the modules that contain the Web
services you want to access.
2.
3.
In your Visual Studio .NET project, add the Web services as Web References.
66
6 - Accessing ATG Web Services from .NET Clients
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.
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.
67
6 - Accessing ATG Web Services from .NET Clients
Atg.DotNet.WebService.Repository.GetItem;
Atg.DotNet.WebService.Repository.PerformRQLQuery;
Atg.DotNet.WebService.UserSession.LoginUser;
Atg.DotNet.WebService.UserSession.LogoutUser;
68
6 - Accessing ATG Web Services from .NET Clients
RepositoryItem Class
Property Class
RepositoryItemRef Class
ComplexType Class
NoSuchPropertyException Class
RepositoryItemSerializer Class
RepositoryItemSerializationException Class
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 in the Java client chapter.
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 dont exist in .NET and so values for these types are converted as follows:
ATG Date or Timestamp properties are stored as .NET DateTime data type.
69
6 - Accessing ATG Web Services from .NET Clients
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 propertys 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:
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.
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 objects RepositoryItem.
Properties
List of properties for this RepositoryItem.
RepositoryId
ID provided to the objects 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
70
6 - Accessing ATG Web Services from .NET Clients
Methods
clearPropertyValues
Clears all property values for a given RepositoryItem. Before using
RepositoryItemSerializer.deserialize, its 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
Returns the propertys 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 propertys 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 RepsoitoryItem setPropertyValue 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 propertys value.
71
6 - Accessing ATG Web Services from .NET Clients
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
Initializes the ItemRef to refer to the provided RepositoryItem.
Properties
TypeName
Data type for the RepositoryItem property.
Properties
Name of any properties that are either deserialized from or serialized into the complex type.
72
6 - Accessing ATG Web Services from .NET Clients
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.
Constructors
RepositoryItemSerializer()
Constructs a serializer instance.
RepositoryItemSerializer(RepositoryItem)
Constructs an object holding serialized content.
73
6 - Accessing ATG Web Services from .NET Clients
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.
74
6 - Accessing ATG Web Services from .NET Clients
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 (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 facility (described in Part I
of this guide) and the Integration Repository.
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.
Adapters that enable the ATG platform and the remote system to communicate
through the middleware transport layer
75
Part II: Integration Framework
ATG 7
RPC
Data Integration
(Integration Repository,
Repository to XML)
Integrator
Adapter
Middleware Transport
Adapter
Remote System
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.
76
Part II: Integration Framework
7 Integration Repository
The ATG Integration Framework includes the Integration Repository, which adds to ATGs 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 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 section of this chapter. Each
command involves an RPC call that may access the remote system, as described in the Remote Procedure
Calls chapter.
The Integration Repository enables you to use ATGs 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
77
7 - Integration Repository
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 for more details about how this approach could be configured.
78
7 - Integration Repository
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 for more details about how this approach could be
configured.
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 for more details about how this approach could be
configured.
79
7 - Integration Repository
Local Only
This approach doesnt 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 doesnt need to issue commands against the remote
system in real time, there doesnt need to be an Integration Repository.
Advantages:
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.
2.
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.
5.
Create any mapping files you desire for each item descriptor in the Integration
Repository. See Mapping for more information.
6.
7.
Create Commands that correspond to each of the command operations you want to
define for your Integration Repository. See the Remote Procedure Calls 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.
80
7 - Integration Repository
<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
81
7 - Integration Repository
$class=atg.adapter.integrations.IntegrationRepository
repositoryName=MyStuff
localRepository=/mystuff/MyLocalRepository
definitionFile=/mystuff/irConfig.xml
transactionManager=/atg/dynamo/transaction/TransactionManager
integrationRepositoryTools=/atg/integrations/repository/IntegrationRepositoryTools
persistentCacheManager=/atg/integrations/repository/PersistentCacheManager
mappingManager=/atg/repository/xml/SchemaManager
mappingTools=/atg/integrations/repository/MappingTools
lockManager=/atg/dynamo/service/ClientLockManager
82
7 - Integration Repository
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 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
$class=atg.adapter.gsa.GSARepository
definitionFiles=/mystuff/localConfig.xml
repositoryName=MyLocalStuff
groupContainerPath=/atg/registry/RepositoryGroups
XMLToolsFactory=/atg/dynamo/service/xml/XMLToolsFactory
transactionManager=/atg/dynamo/transaction/TransactionManager
dataSource=/atg/dynamo/service/jdbc/JTDataSource
idGenerator=/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 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 systems 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 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 in this chapter and see also the Repository to XML Data Binding chapter.
83
7 - Integration Repository
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
INVALID
UNKNOWN
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, 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:
Both the local repositorys query cache and the IntegrationRepositorys 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 in the Command Operations section.
84
7 - Integration Repository
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 that wraps an item descriptor from the local repository.
The local repositorys 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
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
section) execute a Command if one is defined for the item descriptor; otherwise they do nothing.
executeQuery
getItem
updateItem
addItem
removeItem
In addition, this class is responsible for converting the results of queries obtained from the remote system
into repository items.
85
7 - Integration Repository
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 propertys 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"
default-include="false">
<property name="firstName" include="true"/>
<property name="lastName" include="true"/>
<property name="id" target-name="dynamoId" include="true"/>
</item-descriptor>
IntegrationRepositoryView
extends RepositoryViewImpl
86
7 - Integration Repository
this:
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 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
87
7 - Integration Repository
Command Operations
The Integration Repository can define five types of operations that allow ATG repository items to access
data in remote systems:
executeQuery
getItem
addItem
updateItem
removeItem
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.
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:
88
7 - Integration Repository
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 query Command. 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 query Command 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 descriptors 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 descriptors external-id-property).
If getRemoteItem throws an exception, then if the item descriptors 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 items 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.
89
7 - Integration Repository
The input for the updateItem Command 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
updateItem Command. 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.
If you do not configure the derived-properties element for any derived properties in your item, then a
change to a derived propertys 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
90
7 - Integration Repository
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 addItem
Command. 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 defines a mapping file, then the addItem operation creates a MappingRepositoryItem.
Otherwise, the IntegrationRepositoryItem is used.
When the addItem Command 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 systems 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 chapter.
91
7 - Integration Repository
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.
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
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 items
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
items data from the remote system with a getItem operation.
The item descriptor definition in the Integration Repository definition file specifies a local-valuetimeout 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-item Command). If an item is transient, then a
transient instance of the Integration Data repository item would be created.
92
7 - Integration Repository
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).
Property Name
Description
Default Value
expireTimePeriod
deleteInvalidStateItems
true
schedule
Configuration Examples
The following examples show some ways to configure three of the alternatives described in the
Integration Approaches section:
93
7 - Integration Repository
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>
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>
94
7 - Integration Repository
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 GetContacts Command to query and get items.
<gsa-template>
<item-descriptor name="contact" display-property="lastName">
<table name="contact" ... >
<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"/>
95
7 - Integration Repository
<update-item command="/atg/integrations/remotex/UpdateContacts"/>
</item-descriptor>
</integration-repository-template>
<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>
</integration-repository-template>
integration-repository-template tag
96
7 - Integration Repository
header tag
item-descriptor tag
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.
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.
external-idproperty
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.
97
7 - Integration Repository
local-valuetimeout
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.
allow-localoperation
query tag
get-item tag
add-item tag
update-item tag
remove-item tag
The operations defined by these tags are also described in the Command Operations section.
query Tag
This configures the behavior of the Integration Repository when the executeQuery method is called on
the RepositoryView for items of this type.
98
7 - Integration Repository
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.
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 as a child element. See updateItem
and Derived Properties in the Command Operations section.
99
7 - Integration Repository
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.
remove-item Tag
This configures the behavior of the Integration Repository when removeItem is called for repository
items of this type.
100
7 - Integration Repository
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 derivedproperties 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. See updateItem and Derived Properties in the Command Operations section. See also
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 derivedproperties element.
name
referenced-property
If changed-properties-only="true" in the update-item element, then whenever the referencedproperty is sent in the update command, the property specified by the name attribute will be as well. See
updateItem and Derived Properties in the Command Operations section.
101
7 - Integration Repository
(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?)>
<!-- Name of template -->
<!ELEMENT name (#PCDATA)>
<!-- The author(s) -->
<!ELEMENT author (#PCDATA)>
<!-- Version string -->
<!ELEMENT version (#PCDATA)>
<!-- Description string -->
<!ELEMENT description (#PCDATA)>
<!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>
102
7 - Integration Repository
<!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
>
<!ELEMENT derived-properties (property+)>
<!ELEMENT property EMPTY>
<!ATTLIST property
name CDATA #REQUIRED
referenced-property CDATA
>
#REQUIRED
103
7 - Integration Repository
104
7 - Integration Repository
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
Implementing the RPC API
Executing Commands in Pages
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.
105
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:
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:
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:
106
8 - Remote Procedure Calls
If the command is not in the cache, execute the command, return the result, and cache
the command and result.
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.
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 context Map. It is included in the CommandResult
object to provide a way to store additional information that is not part of the result object.
107
8 - Remote Procedure Calls
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:
times out. This is a special case, since a timeout doesnt indicate whether the RPC call
succeeded or not.
108
8 - Remote Procedure Calls
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"/>
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
beans properties file.
However, there is a way you can specify default values for the command parameters in the servlet beans
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.
109
8 - Remote Procedure Calls
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 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>
110
8 - Remote Procedure Calls
Index
.
.NET clients
ATGWS.dll, 68
before calling Web services, 65
calling Web services, 63
client stubs, 64
security, 63
session sharing, 64
transactions, 64
Web service call examples, 67
A
about ATG Web services, 53, 63
accessing ATG Web services from .NET clients, 63
accessing ATG Web services from Java clients, 53
addItem operations, 90
add-item tag, 100
AddService, 48
data validation, 48
C
client stubs for .NET, 64
client stubs for Java clients. See static Web service calls
command operations
addItem, 90
executeQuery, 88
getItem, 89
Integration Repository, 88
removeItem, 91
updateItem, 89
111
Index
CommandHandlers, 106
CommandResults, 107
commands, 106
executing, 106
executing in pages, 108
invoking, 106
CookieContainer, 54, 64
.Net client example, 67
Java client example, 58, 59
custom Web services, 11
D
data binding
repository to XML. See repository to XML data binding
data validation, 48, 49
definition files
Integration Repository, 81, 96
derived properties
updating, 90
derived-properties tag, 101
deserializing content on the client side, 60, 68
dot Net clients. See .NET clients
DTDs
Integration Repository, 101
repository to XML mapping files, 38
dynamic Web service calls, 59
distinction from static calls, 56
limitations, 56
Dynamo Administration UI
Web service creation wizard, 13, 27
Web service registry, 23
Web service security manager, 22
queries, 87
setting up, 80
IntegrationRepository component, 81, 83
IntegrationRepositoryView, 77
item-descriptor tag, 97
itemRef attribute, 45
J
Java clients
before calling Web services, 55
calling Web services, 53
CookieContainer, 54, 58, 59
deserializing content, 60
dynamic Web service calls, 59
installing Axis and ATG extension, 56
security, 53
serializing content, 60
session sharing, 54
static Web service calls, 57, 59
transactions, 54
two ways to call Web services, 56
JAX-RPC, 12
deployment descriptor, 20
mapping file, 20
JMS Web services, 27
MessageImporter component, 28
Patch Bay configuration, 28
executeQuery operations, 88
mapping files
DTD, 38
example, 39
repository to XML data binding, 38
MappingRepositoryItem, 86
MessageImporter component, 28
generateXMLSchema utility, 43
getItem operations, 89
get-item tag, 99
GetService, 46
namespaces
XML Schema, 47
Nucleus component Web services, 14
I
Installing ATGWS.dll, 65
installing Axis and ATG extension, 56
Integration Data repository, 92
cleaning up, 93
Integration Repository, 77
APIs, 82
architecture, 77
command operations, 88
definition files, 81, 96
DTD, 101
examples, 93
operations, 77
persistent cache, 92
O
operations
repository items, 77
112
Index
org.apache.axis.cookies.CookieContainer. See
CookieContainer
P
Patch Bay configuration for JMS Web services, 28
persistent cache. See Integration Data repository
propertyElementNameSeparator, 45
queries
executeQuery operation, 88
Integration Repository, 87
query tag, 98
updateItem operations, 89
derived properties, 90
UpdateService, 49
data validation, 49
updating repository items
from XML documents, 49
validating data
AddService, 48
UpdateService, 49
S
Scenario Manager
receiving messages from JMS Web services, 29
SchemaManager component, 44
Serializing content on the client side, 60, 68
service endpoint interface, 16
service interface class, 16
session sharing
example, 58, 59, 67
sessions
sharing (.NET clients), 64
sharing (Java clients), 54
W
Web service security, 20
NucleusSecurityManager, 21
NucleusSecurityRepository, 22
Web services
Administration UI, 13, 27, 31
ATG Web services, 8, 23
before calling from .NET, 65
before calling from Java clients, 55
calling from .NET clients, 63, 66
calling from Java clients, 53, 56, 59
client stubs for .NET, 64
custom Web services, 11
deploying, 22
generating, 12
infrastructure, 7
JMS messages, 27
limitations, 12
managing, 23
naming restrictions, 15
Nucleus component methods, 14
overview, 11
repository items, 31
runtime classes, 20
security, 12, 53, 63, 64
transactions, 54, 64
wizard, 13, 27
web.xml files, 17
WSDL documents, 16
X
XML documents
generating from repository items, 46
transforming into repository items, 48
updating repository items, 49
113
Index
itemRef attribute, 45
namespace, 47
references to other repository items, 45
repository to XML data binding, 43
114
Index