Access the IBM Initiate Java SDK Javadoc Information 14. Extending the ESOA ...
The IBM Initiate IBM Initiate Enterprise Service Oriented Architecture (ESOA).
IBM Initiate
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide Version 9 Release 7
SC19-3148-01
IBM Initiate
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide Version 9 Release 7
SC19-3148-01
Note Before using this information and the product that it supports, read the information in “Notices and trademarks” on page 57.
© Copyright IBM Corporation 1995, 2011. US Government Users Restricted Rights – Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
Contents Introduction . . . . . . . . . . . . . v System requirements
.
.
.
.
.
.
.
Chapter 1. ESOA Toolkit basics
.
.
. v
. . . . 1
How does it work? . . . . . . . . . Architecture . . . . . . . . . . Getting started. . . . . . . . . . . Adding the generated ESOA source code to IBM Initiate Workbench class path . . .
Chapter 2. Extensibility options
.
. . . . . . the . .
. 1 . 1 . 2 . 2
. . . . 3
Customize the API . . . . . . . . . . . . 3 Customizing object names . . . . . . . . . . 4 Object to Workbench property map . . . . . . 5 ESOA APIs to create callout handlers . . . . . . 7 Access mapping methods . . . . . . . . . 7 Access the GenericMasterDataService . . . . . 8 Authentication. . . . . . . . . . . . . 9 Mapping overview . . . . . . . . . . . 9 Example pre/post usage . . . . . . . . . 9 Example EntMng usage . . . . . . . . . 10
Chapter 3. Generating a Java API and web service . . . . . . . . . . . . 13 Running the generation utility . . . . . . . Java class path settings . . . . . . . . . Access the IBM Initiate Java SDK Javadoc Information Extending the ESOA API . . . . . . . . . Generating the code . . . . . . . . . Library paths . . . . . . . . . . . . Classes to use . . . . . . . . . . . Compiling and packaging . . . . . . . Adding the generated ESOA source code to the IBM Initiate Workbench class path. . . . . Next steps . . . . . . . . . . . . . .
. 13 . 14 14 . 14 . 14 . 15 . 15 . 16
© Copyright IBM Corp. 1995, 2011
. . . . .
. . . . .
. . . . .
19 . . . . .
Creating the Java client . . . Login provider . . . . . Context Provider . . . . GenericMasterDataService . Example: Retrieving records . . Example: Retrieving relationships Additional code samples . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
23 24 24 25 25 26 28
Chapter 6. Creating a client using the web services . . . . . . . . . . . . 37 Creating the web service client . . . . . . . Login provider . . . . . . . . . . . Examples . . . . . . . . . . . . . . How to use the generated JAX-WS client stubs How to use the generated API classes (madclient.jar) with CXF . . . . . . . . How to use the C# Microsoft .NET client stubs Using soapUI to invoke the web services . .
. 37 . 38 . 39 40 . 40 40 . 41
Chapter 7. RESTful services . . . . . 43 Installing the service layer . . . . . . . . Configuring the embedded REST server . . . Configuring the stand-alone application server Supported stand-alone REST server runtime properties . . . . . . . . . . . . . The IBM Initiate Flexible Search REST API . . Accessing the documentation . . . . . . . Client application headers . . . . . . . . Example of a client application . . . . . .
. 43 . 44 45 . . . . .
46 49 50 50 50
Appendix. Troubleshooting . . . . . . 53 . 16 . 17
Chapter 4. Deploying the web service Setting runtime properties . . . . Supported runtime properties . . War deployment. . . . . . . . IBM WebSphere Application Server Oracle WebLogic Server . . . .
Chapter 5. Creating a client using the Java API . . . . . . . . . . . . . . 23
. . . . .
19 20 21 21 21
Legal Statement. . . . . . . . . . . 55 Notices and trademarks . . . . . . . 57 Index . . . . . . . . . . . . . . . 61 Contacting IBM . . . . . . . . . . . 63
iii
iv
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
Introduction The IBM® Initiate® Enterprise Services Oriented Architecture (ESOA) Toolkit is v a Java application programming interface (API) generator v a SOAP-based web service generator v a REST-based web service The IBM Initiate IBM Initiate Enterprise Service Oriented Architecture (ESOA) Toolkit generates an API in both Java and Web Service forms; the REST web service is not generated. The operations available in the generated Java API and generated web service API are the same; you can accomplish the same things in both APIs. REST web services support all the operations that the two generated APIs support with a few exceptions (below). The following operations are supported: v search and retrieve member and relationship data v edit, add and delete member and relationship data (these operations for relationship data are not supported for RESTful web services) v compare and score member data v merge and unmerge member records The Java API is intended to be easier to use than our existing Java SDK, but it is not a complete replacement. There are some things you can do with the existing SDK that you cannot do with the generated API, such as operations on attribute history and tasks. The RESTful web service also supports operations pertaining to: v member, entity, attribute and field labels v member attribute order v member, entity and attribute display templates v member and entity default cvws Refer to Chapter 7, “RESTful services,” on page 43 for more information on the REST service. This document often refers to the paths in the Initiate IBM Initiate Workbench project, using variables for actual paths. A path such as \workspace\project_name\ client\ might refer to C:\Documents and Settings\jdoe\MyWorkspace\Alpha\ client, where the workspace denotes the workspace path selected when you started IBM Initiate Workbench, and projectname denotes the project name within IBM Initiate Workbench.
System requirements Refer to IBM Initiate Master Data Service System Requirements for detailed information on system requirements for using the Initiate IBM Initiate Enterprise Service Oriented Architecture (ESOA) Toolkit, including supported web application servers and their versions.
© Copyright IBM Corp. 1995, 2011
v
vi
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
Chapter 1. ESOA Toolkit basics The IBM Initiate Enterprise Service Oriented Architecture (ESOA) Toolkit generates an API for both Java and web service developers. If your interest is in the RESTful services, skip to Chapter 7, “RESTful services,” on page 43. Which API you use to develop your applications is determined by your particular network environment. Java and web service methods enable you to: v search and retrieve member and relationship data (memsearch, memget, relsearch, relget) v edit, add and delete member and relationship data (memput, memputqual, relput, memdelete, memundelete, reldelete, memdrop) v compare and score member data (memcompare, memscore) v merge and unmerge member data (memmerge, memunmerge) v undo recent put, merge and delete record operations using audrecno (memundo) v set entity management priority during edit and add operations
How does it work? Once you have configured the Master Data Engine to suit your particular environment, you use the Enterprise Services Generator to generate the API. This wizard creates an API that is custom built for your data model, creating the interactions and objects you need to manipulate and access the data in your Hub. It also creates IBM Initiate Java SDK Javadoc Information describing the classes, methods and objects to which you have access. You then use this API or web service to create custom applications as needed.
Architecture Once the API or web service is generated and compiled, you can view the class hierarchy by opening workspace\project_name\client\docs\index.html. This file shows the class, interface and enumeration hierarchies for the generated code. All classes are descended from one of the com.initiate.client.internal classes, which are descended from java.lang.Object. The IBM Initiate classes are: v v v v v v v
com.initiate.client.internal.BaseAttribute com.initiate.client.internal.BaseMasterDataService com.initiate.client.internal.Entity com.initiate.client.internal.EntityId com.initiate.client.internal.Record com.initiate.client.internal.RecordId com.initiate.client.internal.Relationship
v com.initiate.client.internal.RelationshipId The Interface Hierarchy includes: v com.initiate.client.internal.MasterDataWebService
© Copyright IBM Corp. 1995, 2011
1
Getting started Before generating the API, you will need to install IBM Initiate Workbench, create a project and import a Hub configuration.
Procedure 1. Install IBM Initiate Workbench. Refer to the IBM Initiate Workbench Installation Guide. 2. Create an IBM Initiate Workbench project. Refer to the “IBM Initiate Workbench basics” topic in the IBM Initiate Workbench User's Guide. 3. Import a Hub configuration. Refer to the “Managing projects and Hub connections” topic in the IBM Initiate Workbench User's Guide.
Adding the generated ESOA source code to the IBM Initiate Workbench class path IBM Initiate Workbench does not automatically treat the ESOA classes as Java source code. You can take advantage of Eclipse's Java editing features when extending or modifying the generated ESOA source code.
Procedure 1. Update the class path to include the libraries required to compile the generated source code: a. b. c. d. e.
Right-click the project in the Navigator and click Properties. Select Java Build Path and choose the “Libraries” tab. Click Add Variable.... Select the WORKBENCH_CORE_DIR variable and click Extend.... Select /esoa/lib/madapi2.jar and click OK.
f. Continue to use Add Variable... for the following jars: v /esoa/lib/commons-logging-*.jar v /esoa/lib/geronimo-servlet_*.jar v /esoa/lib/jsr311-api-*.jar g. Click OK. 2. Add the ESOA source code to the class path: a. Right-click the project in the Navigator and click Properties. b. Select Java Build Path and choose the “Source” tab. c. Click Add Folder.... d. Select project/client/src and click OK. e. Click OK.
Results The ESOA source can now be treated as Java source code for easy development.
2
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
Chapter 2. Extensibility options You can customize the API by specifying property names in the api.properties file. The generation utility uses this file to create the custom API.
Customize the API The api.properties file, located in the project's client folder, can include the following keys. These are optional; if not specified, the generation utility will use the defaults listed. Table 1. Optional api.properties keys and values Key
Description
service.packagename
The service.packagename defines the package name of the generated source files. If service.packagename is defined, then all source files will be generated under that package name. Default: com.initiate.client
service.memstat
The service.memstat filters results by member status. You can specify multiple values separated by commas. Valid member status values are Active (A), Overlay (O), Merged (M), Deleted (D) and Fictitious (F). Default: A,O
service.recstat
The service.recstat filters results by record status. Although optional, no attributes (only memHead records) will be returned if this is not set. Typically you would want to get at least 'A'ctive attributes. You can select multiple status codes in the dialog box. Valid values are Active (A), Inactive (I), Deleted (D) and Shadow (S). You can specify multiple values separated by commas. Default: A
Custom Object Names
For the object name properties below, the tokens shown in CAPS are replaced by the property value shown in IBM Initiate Workbench. Refer to “Customizing object names” on page 4 for detailed instructions on using the custom object name properties.
source.SRCCODE.propertyname
Overrides the informational source code name.
record.MEMTYPE.classname
Overrides the member type name.
record.MEMTYPE.attribute. ATTRCODE.propertyname
Overrides the attribute field name on the member type.
record.MEMTYPE.entity.ENTTYPE. classname
Overrides the entity type name.
© Copyright IBM Corp. 1995, 2011
3
Table 1. Optional api.properties keys and values (continued) Key
Description
record.MEMTYPE.source.SRCCODE. propertyname
Overrides the definitional sources for the member type.
relationship.RELTYPE.classname
Overrides the relationship type name.
relationship.RELTYPE.attribute. ATTRCODE.propertyname
Overrides attribute field name on the relationship type.
attributetype.SEGCODE.classname
Overrides the segment type name.
attributetype.SEGCODE.field. FLDNAME.propertyname
Overrides field name on the segment type.
Advanced customization properties service.webserviceintf
The name of a custom web service interface class. This property is used if you want to extend the MasterDataService with your own custom interface. The custom interface will not be generated automatically and must be provided by the user. The service.webserviceimpl property (below) must also be specified to match the custom interface. See “Extending the ESOA API” on page 14 for more information. Default: MasterDataWebService
service.webserviceimpl
The name of the web service implementation class. This property is used if you want to extend the MasterDataService with your own custom implementation. The custom implementation will not be generated automatically and must be provided by the user. The service.webserviceintf property (above) must also be specified to match the custom implementation. See “Extending the ESOA API” on page 14 for more information. Default: MasterDataWebServiceImpl
Customizing object names By default, object names are generated from a specific property within the Hub or algorithm configuration. If you do not want to adjust the property's value in IBM Initiate Workbench, but want to change the name of an object as used in the API or web service, you can set the desired values in the workspace\project_name\client\ api.properties file.
About this task The object name customization keys are commented out in the api.properties file. To use them, you would remove the pound (#) symbol in front of the desired property and replace the uppercase tokens with actual property values found in IBM Initiate Workbench as described in Table 2 on page 5. If you do not override these properties, the API and web service will be generated with the values shown in IBM Initiate Workbench.
4
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
You can use an equal sign (=), colon (:) or space character to make the assignment. The following lines are valid examples of what might appear in the api.properties file: record.person.classname=customer record.person.attribute.lglname.propertyname:full_name record.person.attribute.homephon.propertyname primary_phone Note: Object and property keys and values must not contain spaces.
Procedure 1. Determine the property you wish to change from “Customize the API” on page 3. For example, we want to override the segment type name: attributetype.SEGCODE.classname. 2. Consult Table 2 for the capitalized token, and determine which IBM Initiate Workbench property is substituted. For our example, SEGCODE corresponds to the Attribute Types: Member/Relationship Attribute Types: Attribute Type: Code property. 3. In IBM Initiate Workbench, open the Hub Configuration editor and navigate to the property shown in step 2 and note its value. In our example, we select the Member Relationship attribute type and the MEMADDR attribute, and see that the Code property's value is MEMADDR. 4. In the api.properties file, add the desired property, substituting the capitalized token for the IBM Initiate Workbench value. For this example, we add the property attributetype.memaddr.classname to the api.properties file. 5. In the api.properties file, set the desired value for the property. The example becomes attributetype.memaddr.classname=memberAddress. Now, when we generate the API, the MEMADDR class will be called memberAddress.
Object to Workbench property map The object name customization keys are commented out in the api.properties file. To use them, remove the pound (#) symbol in front of the desired property and replace the uppercase tokens with actual property values found in IBM Initiate Workbench. The table below shows the objects that are substitutable, and their corresponding IBM Initiate Workbench properties. Table 2. Object to IBM Initiate Workbench property mapping Object
Property
MEMTYPE
Member Type: Label
ATTRCODE
Member Type: Attributes: Code
ENTTYPE
Member Type: Entity Type: Name
SRCCODE
Member Type: Sources: Source Code
SEGCODE
Attribute Types: Member/Relationship Attribute Types: Attribute Type: Code
FLDNAME
Attribute Types: Member Attribute Types: Attribute Type: Fields: Field label
Examples
Chapter 2. Extensibility options
5
Our example Hub configuration has a member type object called ORGANIZATION, whose IBM Initiate Workbench properties are as follows. Property Value Category ORGANIZATION Derivation code DVDORG Derivation description Derivation name DERIVATION ORGANIZATION Description Label
Corporate Identity
Memtypeno 4 Name ORGANIZATION Optimized Put Mode false Uses history false We want to change the Organization Address property from orgaddr (the default) to “bus_address” in the generated API. By default, the object name in the generated API would be CorporateIdentity, as indicated by the Member Type's Label property minus any spaces. This member type has an Attribute called Organization Address, and you could change the object name of that attribute in the generated code by first locating its Code property in IBM Initiate Workbench and setting the corresponding key to the Code's value, and then making the assignment to the desired value: record.CorporateIdentity.attribute.orgaddr.propertyname=bus_address Property Value Attrrecno 401 Code
ORGADDR
Description Organization Address Enumerated data type code Label
Organization Address
Maximum active values 1 Maximum existing values 0
6
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
Member status filter AO Name Organization Address Storage type normal Type
MEMADDR
Say, for example you do not want to use the classname “CorporateIdentity” in the API and wanted to change it to “Company.” Instead of typing record.MEMTYPE.classname=company in the properties file, you would substitute the corresponding Member Type: Label property's value (minus spaces) for MEMTYPE: record.corporateidentity.classname=company Likewise, instead of typing record.MEMTYPE.attribute.ATTRCODE.propertyname=bus_address, you would substitute the Member Type: Label value for MEMTYPE, and the Member Type: Attributes: Code value for ATTRCODE: record.corporateidentity.attribute.orgaddr.propertyname=bus_address Note: Use unique names throughout the properties file. Naming the memtype.classname and the entity.classname the same thing, for example, might cause errors. Some additional examples are: record.corporateidentity.entity.org.classname=corp record.corporateidentity.source.ordr.propertyname=order attributetype.memaddr.classname=corpAddress attributetype.memaddr.field.stLine1.propertyname=addressLine1
ESOA APIs to create callout handlers Support has been added to the existing callback handler framework to allow the Generic Master Data Service to be used from Pre-/Post- and Entity-managed callback handlers. This allows the complexity of core Java SDK data types to be abstracted behind both the GenericMasterDataService and the services provided for mapping generic entities and records. In order to provide the generic functionality for a new or existing callback handler, it must simply inherit from the madison.handler.HandlerGenericBase class within the Java SDK. The class hierarchy for HandlerGenericBase extends from madison.handler.HandlerExtBase, thus providing all of the functionality recommended for implementing handlers such as logging, etc.
Access mapping methods A number of methods are present within the HandlerGenericBase class that deal with the various permutations of mapping MemRowLists and both singular/multiple generic types.
Chapter 2. Extensibility options
7
Member-based methods protected GenericRecord toGenericRecord(IService service, MemRowList memRL) protected List toGenericRecords(IService service, MemRowList memRL) protected MemRowList toMemberRowList(IService service, List genericRecords, MemRowList sourceMemRL) protected GenericRecord toGenericRecord(IService service, MemRowList memRL, String userName, String password) protected List toGenericRecords(IService service, MemRowList memRL, String userName, String password) protected MemRowList toMemberRowList(IService service, List genericRecords, MemRowList sourceMemRL, String userName, String password) protected MemRowList toMemberRowList(IService service, GenericRecord genericRecord) protected MemRowList toMemberRowList(IService service, List genericRecords) protected MemRowList toMemberRowList(IService service, GenericRecord genericRecord, String userName, String password) protected MemRowList toMemberRowList(IService service, GenericRecord genericRecord, MemRowList sourceMemRL) protected MemRowList toMemberRowList(IService service, GenericRecord genericRecord, MemRowList sourceMemRL, String userName, String password)
Entity-based methods protected HandlerGenericEntity toGenericEntity(IService service, MemRowList memRL) protected List toGenericEntities(IService service, MemRowList memRL) protected HandlerGenericEntity toGenericEntity(IService service, MemRowList memRL, String userName, String password) protected List toGenericEntities(IService service, MemRowList memRL, String userName, String password) protected MemRowList toEntityRowList(IService service, HandlerGenericEntity genericEntity, MemRowList sourceMemRL, String userName, String password) protected MemRowList toEntityRowList(IService service, HandlerGenericEntity genericEntity, String userName, String password) protected MemRowList toEntityRowList(IService service, HandlerGenericEntity genericEntity) protected MemRowList toEntityRowList(IService service, List genericEntities) protected MemRowList toEntityRowList(IService service, HandlerGenericEntity genericEntity, MemRowList sourceMemRL) protected MemRowList toEntityRowList(IService service, List genericEntities, MemRowList sourceMemRL) protected MemRowList toEntityRowList(IService service, List genericEntities, String userName, String password) protected MemRowList toEntityRowList(IService service, List genericEntities, MemRowList sourceMemRL, String userName, String password)
Access the GenericMasterDataService The HandlerGenericBase class offers two methods for retrieving an instance of the GenericMasterDataService: protected GenericMasterDataService getGenericMasterDataService(IService service) protected GenericMasterDataService getGenericMasterDataService(IService service, String userName, String password)
Note that any service method call executed on the generic master data service instance will re-use the connection context from the supplied IService instance. For usage information on the generic master data service, refer to “GenericMasterDataService” on page 25.
8
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
Authentication In some of the method overloads defined above, user credentials can be specified. These credentials are used primarily to create a default login provider required for the underlying mapping and master data service to use (i.e. used for acquiring service metadata, execution of interactions etc.). If user credentials are not passed to the target method, then the underlying code will reuse the credentials within the supplied IService instance (specifically within the nested context). Note: This is only applicable for pre- and post- callback handlers; entity management callback handlers must supply valid user credentials.
Mapping overview In order to use generic types within a callback handler, you must first decide where the data resides within the IService instance which requires mapping (input/output member row list). Then you are free to use the mapping methods within the HandlerGenericBase class to split the member row list into the desired generic types (i.e. GenericEntity/GenericRecord). Each mapped type can be manipulated or used in conjunction with the generic Master Data Service. If the changes made to the generic types must be reflected in the output or input for the IService instance, the generic type(s) can be mapped back into a member row list and stored on the IService instance. At this time, the generic mapping support is only targeted at modelling record data (i.e. attributes); other types such as EntLink will be ignored, but the non-modeled information can still be preserved. For example, if the method toGenericEntity(...) was executed on the output member row list (from the IService instance), the generic entity returned would only contain a breakdown of the specific Generic records that make up the entity (each generic record would contain only attribute data as well as the record identifier). In order to preserve any additional information within the source input row list (linkage, tasks, etc.), mapping methods have been supplied to translate the generic types back into a member row list and include any additional information from the original member row list. GenericEntity entity = toGenericEntity(service,service.getOutMemRowList()); //Manipulate entity service.setOutMemRowList(toEntityRowList(service,entity,service.getOutMemRo wList()));
Note that the underlying low level information such as member record numbers, audit, match information etc will be preserved when mapping to and from the target types (i.e. generic/member row list). By default, the generic mapper implementation for the callback handlers will provide an instance of a generic record which is cast to com.initiate.client.generic.GenericRecord, however if the low level information is required from a mapped generic record type it can be cast to the madison.mpi.HandlerGenericRecord class for low level usage.
Example pre/post usage This example shows how a pre and post handler can be written to log out record information. package com.initiatesystems.sandpit.handler; import java.util.List; import madison.handler.HandlerGenericBase; import madison.handler.IService; import madison.mpi.MemRowList;
Chapter 2. Extensibility options
9
import com.initiate.client.generic.GenericRecord; /** * Example generic handler */ public class RecordLogHandler extends HandlerGenericBase { /* * (non-Javadoc) * @see madison.handler.HandlerExtBase#preIxn(madison.handler.IService) */ @Override public void preIxn(IService service) { logRecords(service, service.getInpMemRowList()); } @Override public void postIxn(IService service) { logRecords(service, service.getOutMemRowList()); } /** * Splits the input member row list into seperate GenericRecords and logs them. * * @param service IService object * @param memRL Member row list to log */ public void logRecords(IService service, MemRowList memRL) { if (isTraceEnabled()) { List records = toGenericRecords(service, memRL); if ((records != null) && (records.size() > 0)) { for (GenericRecord record : records) { trace(record.toString()); } } } } }
Example EntMng usage This example shows how the generic master data service can be used from an entity management callback handler. package com.initiatesystems.sandpit.handler; import java.util.List; import java.util.Properties;
10
import import import import import
madison.handler.HandlerGenericBase; madison.handler.IService; madison.mpi.EntLink; madison.mpi.RowIterator; madison.util.ClassTest;
import import import import
com.initiate.client.generic.GenericEntity; com.initiate.client.generic.GenericEntityId; com.initiate.client.generic.GenericMasterDataService; com.initiate.client.internal.MasterDataServiceException;
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
public class EntityLogHandler extends HandlerGenericBase { private Properties properties; private static final String KEY_USER = "user"; private static final String KEY_PASSWORD = "password"; //..do initialization code to populate properties /* * (non-Javadoc) * @see madison.handler.HandlerExtBase#entMng(madison.handler.IService) */ public void entMng(IService service) { try { if ((isTraceEnabled()) && (service.getInpMemRowList().size() > 0)) { RowIterator itr = service.getInpMemRowList().rows(new ClassTest(new EntLink())); if ((itr != null) && (itr.rowCount() > 0)) { //fetch entity identifiers List ids = ... String [] attributes = ... GenericMasterDataService mds = getGenericMasterDataService(service, properties.getProperty(KEY_USER), properties.getProperty(KEY_PASSWORD)); List entities = mds.getEntityListByEntityIds(ids, service.getEntType(), null, null, attributes); if ((entities != null) && (entities.size() > 0)) { for (GenericEntity entity : entities) { trace(entity.toString()); } } } } } catch (MasterDataServiceException ex) { error(ex.getMessage(), ex); //delegate error ... } } }
Chapter 2. Extensibility options
11
12
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
Chapter 3. Generating a Java API and web service About this task The API and SOAP web service are easily created using the Enterprise Services Generator, a wizard that generates, compiles and packages the API into a ready-to-use JAR and WAR file.
Running the generation utility The API and web service generation utility is run from IBM Initiate Workbench. Details about the configuration and algorithms are retrieved from the project, not from the Hub(s) associated with that project. Deploy the configuration prior to generating the Java API so that the Hub and generated API code are in sync.
Before you begin Be sure the following prerequisites are met: v A version 9.7 or later Master Data Engine must be installed and accessible from the computer on which the IBM Initiate Enterprise Service Oriented Architecture (ESOA) Toolkit will be used. v The corresponding version of IBM Initiate Workbench must also be installed. v The data dictionary and algorithms should be fully configured in IBM Initiate Workbench before you generate the API. The classes, objects and methods created by the IBM Initiate Enterprise Service Oriented Architecture (ESOA) Toolkit are specific to your member types. Refer to “Access the IBM Initiate Java SDK Javadoc Information” on page 14 for source code documentation information. v You must have a deployed IBM Initiate Workbench project to use the generated API.
Procedure 1. Use the Initiate > Generate Enterprise Services... menu. The Generate Enterprise Services dialog opens. 2. Select the project for which you wish to generate the API. 3. If you wish to specify generation options, leave the Use custom source generation properties checkbox enabled. This will read in the property settings from the workspace\project_name\client\api.properties file. Refer to “Customize the API” on page 3 for details on customizing the properties file. 4. If you have previously generated the source code and want to delete the contents of the workspace\project_name\client\src directory, leave Clean the client source directory enabled. If you have customized the API source code and do not want to delete the src directory files, uncheck this option. 5. If you want the utility to generate the object API source code files, leave Clean the client source directory enabled (default). Disabling this option instructs the utility to omit generating the .java files. In cases where you have modified the source code in the generated .java files, disabling this option will prevent the utility from generating the source code and overwriting any changes you have made. 6. If you want the utility to automatically compile the source code, generate the IBM Initiate Java SDK Javadoc Information and Package service with compiled © Copyright IBM Corp. 1995, 2011
13
source, documentation and web service, leave that option enabled (default). Disabling this option instructs the utility to omit compiling the source code, generating the IBM Initiate Java SDK Javadoc Information and creating the distribution files. You can execute the utility with this option later to create the deployment package. The compiled .class files are placed in the workspace\project_name\client\classes folder, and the madclient.jar and madclient.war files are created in the workspace\project_name\client\dist folder. 7. Click Finish.
Java class path settings Those using the Java API will need to update their class path with the following: v dist\madclient.jar - generate ESOA classes specific to your data model v lib\madapi.jar - core IBM Initiate Java API v lib\madapi2.jar - common ESOA API classes v lib\madcommon.jar - common IBM Initiate classes v lib\commons-lang-*.jar v lib\commons-logging-*.jar v lib\commons-pool-*.jar
Access the IBM Initiate Java SDK Javadoc Information The Javadoc Information is generated based on your specific Hub configuration metadata. Once the object API source code is compiled and packaged (see “Running the generation utility” on page 13), IBM Initiate Java SDK Javadoc Information is created to describe the classes and methods specific to your implementation. The project's \docs folder (workspace\project_name\client\docs\help-doc.html) contains several HTML files of interest, which can be opened in IBM Initiate Workbench or in your chosen web browser. Consult the help-doc.html file to learn about the organization of the Javadoc HTML documentation.
Extending the ESOA API The generated ESOA Java API and web services API can be extended to provide custom logic to any part of the API.
About this task Note: IBM Initiate does not support customizations to the generated ESOA code. This information is provided for your convenience.
Generating the code About this task Details about the configuration and algorithms are retrieved from the project, not from the Hub(s) associated with that project.
14
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
Procedure 1. In IBM Initiate Workbench, use the Initiate > Generate Enterprise Services... menu. The Generate Enterprise Services dialog opens. 2. Select the project for which you wish to generate the API. Note: Deploy the configuration prior to generating the Java API so that the Hub and generated API code are in sync. 3. Enable the Clean the client source directory and Generate client source code options. 4. Disable the Package service with compiled source, documentation and web service option. 5. Click Finish.
Results Now you can customize the generated classes located in workspace\project_name\ client\src.
Library paths The libraries found in workbench install path\com.ibm.workbench_9.7.x \esoa\lib are used when compiling the generated ESOA source plus any custom modifications. All third party library jars and classes required by the custom code must be located in workspace\project_name\client\WEB-INF\lib and workspace\project_name\client\WEB-INF\classes respectively. Create these directories if they do not already exist. Any third party libraries in this location are used when compiling the ESOA code and automatically packaged into the madclient.war distribution.
Classes to use To extend the ESOA web services API, the recommended approach is to extend the MasterDataServiceImpl and MasterDataWebService classes. Any custom methods must be added to both the implementation and interface classes. The new custom extension classes must be located in the same package as the other generated code in workspace\project_name\client\src. package com.initiate.client; public class MyMasterDataServiceImpl extends MasterDataWebServiceImpl implements MyMasterDataService { public String helloESOA(String arg) { return "Hello " + arg; } } package com.initiate.client; import javax.jws.*; @WebService public interface MyMasterDataService extends MasterDataWebService { @WebResult(name="helloESOA") public String helloESOA(@WebParam(name="arg") String arg); }
Chapter 3. Generating a Java API and web service
15
Add the following properties to workspace\project_name\client\api.properties when extending the MasterDataWebService classes: v service.webserviceintf=MyMasterDataService v service.webserviceimpl=MyMasterDataServiceImpl This will cause the madclient.war package to use the custom classes as the service implementation.
Compiling and packaging About this task This procedure compiles the code and packages it into a ZIP file containing the API files.
Procedure 1. In IBM Initiate Workbench, use the Initiate > Generate Enterprise Services... menu. The Generate Enterprise Services dialog opens. 2. Select the project for which you wish to package the API. Note: Details about the configuration and algorithms are retrieved from the project, not from the Hub(s) associated with that project. Deploy the configuration prior to generating the Java API so that the Hub and generated API code are in sync. 3. Disable the Clean the client source directory and Generate client source code options. 4. Enable the Package service with compiled source, documentation and web service option. 5. Click Finish.
Results The new custom method now appears with the other the methods on MasterDataService.
Adding the generated ESOA source code to the IBM Initiate Workbench class path About this task IBM Initiate Workbench does not automatically treat the ESOA classes as Java source code. To take advantage of Eclipse's Java editing features when extending/modifying the generated ESOA source code, follow this procedure:
Procedure 1. To update the class path to include the libraries required to compile the generated source code: a. Right-click the project in the Navigator and select Properties. b. Select Java Build Path and choose the Libraries tab. c. Click Add Variable.... d. Select the WORKBENCH_CORE_DIR variable and click Extend.... e. Select “\esoa\lib\madapi2.jar” and click OK. f. Repeat steps c-e for the following jars:
16
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
v \esoa\lib\commons-logging-*.jar v \esoa\lib\geronimo-servlet_*.jar v \esoa\lib\jsr311-api-*.jar g. Click OK. 2. To add the ESOA source code to the class path: a. b. c. d. e.
Right click the project in the Navigator and select Properties. Select Java Build Path and choose the Source tab. Click Add Folder.... Select “workspace\project_name\client\src” and click OK. Click OK.
Results The ESOA source can now be treated as Java source code for easy development.
Next steps The next steps vary depending on whether you will be using the Java API or the generated web service. Java API: The output from the source code generation utility will be the ISI_Client_9.7. x .zip file located at workspace\project_name\client. This zip file contains all of the files needed to create client code using the ESOA API: the madclient.jar, the IBM Initiate Java SDK Javadoc Information, and all required libraries. You can extend the workspace\project_name\client\src\*.java source code files as needed and recompile, or use as-is. You are now ready to write your applications using the generated API. Refer to Chapter 5, “Creating a client using the Java API,” on page 23. web service: The output from the source code generation utility is the ISI_Client_9.7. x .zip file located at workspace\project_name\client. This zip file contains all of the files needed to create client code using the ESOA API: the madclient.war, the IBM Initiate Java SDK Javadoc Information, the wsdl files, and all required libraries. You are now ready to deploy the web service so that you can create your custom applications using it. Refer to Chapter 4, “Deploying the web service,” on page 19.
Chapter 3. Generating a Java API and web service
17
18
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
Chapter 4. Deploying the web service About this task Once you have generated the web service using the Enterprise Services Generator, you will need to configure the runtime options and then deploy the war to one of the supported web application servers.
Setting runtime properties Properties such as the login provider or Master Data Engine host name and port are specified with the madclient.properties file.
About this task Create the madclient.properties file by following the steps below.
Procedure 1. Create a new text file called madclient.properties. 2. Type (or copy and paste) the following text into the madclient.properties file: loginProvider.classname=com.initiate.client.internal.DefaultLoginProvider loginProvider.username= loginProvider.password= contextFactory.hostName=localhost contextFactory.hostPort=16000 contextFactory.useSSL=false contextFactory.secLib=SSL contextFactory.sslVersion=SSLv3 contextFactory.sslCertVerify=false contextPool.initialSize=0 contextPool.maxSize=10 contextPool.maxWaitMillis=-1 soap.binding.version=1.1
Adjust values as needed to suit your environment. Refer to Table 3 on page 20 for a description of each property. Note: The ESOA web services can be deployed with SOAP version 1.1 or 1.2. The default is version 1.1. Refer to the W3C specification for information on the difference between the versions. The version would only need to change based on a specific requirement within your environment. A version of the WSDL for both SOAP versions is included in the ISI_Client_9.7.x package generated by IBM Initiate Workbench in the \wsdl directory. The madclient-soap12-dotnet.wsdl should be used to generate the .NET client stubs if using SOAP version 1.2. 3. Navigate to the directory that contains madclient.war file. 4. Create the subdirectory WEB-INF\classes. 5. Place the madclient.properties file in WEB-INF\classes. 6. On the command line, use the command jar uf madclient.war WEB-INF\classes\madclient.properties to embed the properties file in the war file. Alternatively, you could place the madclient.properties file in a common location accessible by the web application server.
© Copyright IBM Corp. 1995, 2011
19
Supported runtime properties The table below describes the supported runtime properties for the web services client. Table 3. Supported runtime properties Property
Description
loginProvider.classname
The class name of the login provider to be used by the web service. The choices are: v com.initiate.client.internal.DefaultLoginProvider - Use this provider if you want all users of the web service to access the Master Data Engine using a fixed username. v com.initiate.client.internal.HttpBasicAuthLoginProvider Use this provider if you want the username/password for the Master Data Engine to be provided by the web service client. The client must provide the username/password using the Http Basic Authentication method. v com.initiate.client.internal.WSSecurityUsernameToken PasswordTextLoginProvider - Use this provider if you want the username/password for the Master Data Engine to be provided by the web service client. The client must provide the username/password using the WS-Security standard. Default: com.initiate.client.internal.DefaultLoginProvider
loginProvider.username
This is the username used to log into the Master Data Engine. It should only be used with the DefaultLoginProvider. Default: none
loginProvider.password
This is the password used to log into the Master Data Engine. It should only be used with the DefaultLoginProvider. Default: none
contextFactory.hostName This is the name (or IP address) of the host running the Master Data Engine. Default: localhost contextFactory.hostPort
This is the network port number for the Master Data Engine. Default: 16000
contextFactory.useSSL
This is true if communication with Master Data Engine is encrypted. Default: false
contextFactory.secLib
Used only if useSSL is true. Default: SSL
contextFactory.sslVersion Used only if useSSL is true. Default: SSLv3 contextFactory.sslCertVerifyUsed only if useSSL is true. Default: false contextPool.initialSize
The number of contexts to create on web application startup. Default: 0
20
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
Table 3. Supported runtime properties (continued) Property
Description
contextPool.maxSize
The maximum number of contexts to create. Default: 10
contextPool.maxWaitMillis The length of time (in milliseconds) to wait for a context to become available before returning an error. Default: -1 (Wait forever) soap.binding.version
The version of the SOAP protocol to use. Must be either 1.1 or 1.2. Default: 1.1
War deployment The war file is deployed in the normal manner for the web application server you are using. Any special considerations are described in the sections below. There are no special deployment steps for Tomcat.
IBM WebSphere Application Server After deploying madclient.war but before starting it, make sure that the classloading behavior for the application is set as follows: v “Class loader order” should be “Classes loaded with local class loader first (parent last)”. v “WAR class loader policy” should be “Single class loader for application”. Note: Depending on the version of IBM WebSphere® you are using, the Context Root is entered either early or later in the deployment process. Be sure to enter madclient as the Context Root when prompted.
Oracle WebLogic Server You can use either the Sun JRE or the Oracle JRockit JRE. If you are using HTTP Basic Authentication (i.e., loginProvider.classname specified in madclient.properties is com.initiate.client.internal.HttpBasicAuthLoginProvider), you will need to disable WebLogic credentials checking for the domain that hosts the application. Consult the Oracle WebLogic documentation for a complete description, but basically you will need to add the following at the end of the securityconfiguration element in the domain config.xml file: false
Chapter 4. Deploying the web service
21
22
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
Chapter 5. Creating a client using the Java API About this task The client application you will write is 100% customized for your particular implementation, and so no two applications will be identical. In this example, we will demonstrate how to access the Master Data Engine from a client program written in Java. Our example Hub was configured using a member type called Person, which has two entities, identity and household.
Creating the Java client The main class in the IBM Initiate Enterprise Service Oriented Architecture (ESOA) Toolkit is the generated MasterDataService (in the com.initiate.client package by default).
Before you begin v You are using a supported version of the Java SDK (refer to the IBM Initiate Master Data Service System Requirements). v You have already generated the Enterprise Services for your IBM Initiate Workbench project.
Procedure 1. Start in a working directory. Copy the ISI_Client_9.7. x .zip file from the workspace\project_name\client\ folder to the working directory. This zip file contains your generated Java API and supporting libraries, as well as the generated documentation. Unzip the ISI_Client_9.7. x .zip file. 2. Create a subdirectory to hold your compiled code. Here we will use the subdirectory classes. 3. Write Java code to access the Master Data Service. 4. Compile and run the code.
Results To use the MasterDataService, implementations of the following interfaces must be provided: v com.initiate.client.internal.MasterDataLoginProvider - analogous to madison.mpi.UsrHead in the core API v com.initiate.client.internal.MasterDataContextProvider - analogous to madison.mpi.Context in the core API These classes tell the MasterDataService the credentials to use to interact with the Engine, and how to connect with Engine, respectively. The most common usage pattern is: 1. Instantiate a MasterDataContextProvider implementation. 2. Instantiate a MasterDataLoginProvider implementation. 3. Instantiate the MasterDataService. 4. Set the LoginProvider and ContextProvider on the MasterDataService. © Copyright IBM Corp. 1995, 2011
23
5. Invoke methods on the MasterDataService. 6. Close the MasterDataContextProvider to release resources. Custom implementations of MasterDataContextProvider and MasterDataLoginProvider can be created by the client as needed.
Login provider There is one implementation of MasterDataLoginProvider that can be used from a Java API client: com.initiate.client.internal.DefaultLoginProvider
How to use the DefaultLoginProvider DefaultLoginProvider loginProvider = new DefaultLoginProvider("system", "system");
Context Provider There are two implementations of MasterDataContextProvider that can be used from a Java API client: com.initiate.client.internal.DefaultContextProvider com.initiate.client.internal.PoolContextProvider
How to use the DefaultContextProvider The DefaultContextProvider is a thin wrapper around the standard Master Data Engine Context object. This implementation should be used in a simple Java application (i.e. a test class that invokes various methods on the ESOA API. Refer to the “Example: Retrieving records” on page 25 or “Example: Retrieving relationships” on page 26 for examples of usage.
How to use the PoolContextProvider The PoolContextProvider should be used when a client application has multiple concurrent clients accessing the ESOA Java API. Use of this implementation is recommended when using the ESOA Java API from a web application. Refer to the IBM Initiate Java SDK Javadoc Information on PoolContextProvider for more information about the various pool settings.
Example: PoolContextProvider import com.initiate.client.MasterDataService; import com.initiate.client.internal.DefaultLoginProvider; import com.initiate.client.internal.PoolContextProvider; public class ESOAClientJava { public static void main(String[] args) { PoolContextProvider ctxProvider = null; try { ctxProvider = new PoolContextProvider(); ctxProvider.setHostName("localhost"); ctxProvider.setHostPort(16090); ctxProvider.init(); MasterDataService svc = new MasterDataService(); svc.setLoginProvider(new DefaultLoginProvider("system", "system")); svc.setContextProvider(ctxProvider); //... perform operation(s) using the svc...
24
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
} finally { if (ctxProvider != null) { ctxProvider.close(); } } } }
GenericMasterDataService The GenericMasterDataService is a non-generated version of the ESOA Java API. All of the functionality of the ESOA layer is exposed, but the API can be used with just the core classes contained in the madapi2.jar (located in the ISI_Client_9.2.0.zip's \lib dir). The Generic beans require the codes and field metadata to be specified when they are used. This differs from the generated ESOA beans that have all the metadata implicitly defined in the bean definition. import import import import import import
com.initiate.client.generic.metadata.ServiceMetaData; com.initiate.client.generic.GenericMasterDataService; com.initiate.client.internal.DefaultLoginProvider; com.initiate.client.internal.DefaultContextProvider; com.initiate.client.internal.MasterDataContextProvider ; com.initiate.client.internal.MasterDataLoginProvider ;
public class ESOAClientJava { public static void main(String[] args) { MasterDataContextProvider ctxProvider = null; try { contextProvider = new DefaultContextProvider("localhost", 16092, null); MasterDataLoginProvider loginProvider = new DefaultLoginProvider("system", "system"); ServiceMetaData serviceMetaData = new ServiceMetaDataBuilder(loginProvider, contextProvider).build(); GenericMasterDataService svc = new GenericMasterDataService(); svc.setLoginProvider(loginProvider); svc.setContextProvider(ctxProvider); svc.setServiceMetaData(serviceMetaData); //... perform operation(s) using the svc... } finally { if (ctxProvider != null) { ctxProvider.close(); } } } }
Example: Retrieving records For this example, we have a member type called Person, and a Person has a LegalName attribute with fields for first and last name. A Person can be identified by a number assigned by source MYSRC. import com.initiate.client.*; import com.initiate.client.internal.*; import java.util.*; public class JavaESOAExample { public static void main( String[] args) Chapter 5. Creating a client using the Java API
25
throws Exception { //Instantiate a service object MasterDataService svc = new MasterDataService(); //We’ll use the default login provider (Fixed user and password) svc.setLoginProvider( new DefaultLoginProvider("hubuser","hubpw")); //We’ll use the default context provider also Properties props = new Properties(); svc.setContextProvider( new DefaultContextProvider("hubhost", 16000, props)); //We’ll look up a specific person PersonId pid = new PersonId(); pid.setMemIdnum("55555"); pid.setSrcCode("MYSRC"); //Create a list to hold the identifiers we’re looking for List pidList = new ArrayList(); pidList.add( pid); //Go get the person(s) from the service List personList = svc.getPersonList( pidList, null, null, null); //Say how many we received System.out.println("Returned " + personList.size() + " person."); //Show their names for( Person person: personList ) { for( Memname name: person.getLegalNameList() ) { System.out.println( name.getOnmFirst() + " " + name.getOnmLast()); } } } }
In this code, you would replace the following items with values appropriate to your Master Data Engine: v v v v
hubuser - Username for your Master Data Engine. hubpw - Password for your Master Data Engine. hubhost - Host name or IP address for your Master Data Engine. 16000 - Port for your Master Data Engine.
With the above assumptions, your compile command would look like this: javac -d classes -cp dist/madclient.jar;lib/madapi2.jar JavaESOAExample.java
With the above assumptions, your run command would look like this: java -cp classes;dist/madclient.jar;lib/madapi2.jar;lib/commons-lang-2.4.jar; lib/commons-logging-1.1.1.jar;lib/commons-pool-1.4.jar;lib/madapi.jar; lib/madcommon.jar JavaESOAExample
The versions of the libraries may be different on your system. Use the versions that are located in the 'lib' subdirectory.
Example: Retrieving relationships For this example, we have a relationship type called Bossof that represents the boss to employee relationship between IdentityEntities. Each boss can have zero to many employees. The boss is represented as the “left” side of the relationship, and the employees are represented as the “right” side of the relationship. import import import public {
26
com.initiate.client.*; com.initiate.client.internal.*; java.util.*; class JavaESOARelationshipExample
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
public static void main( String[] args) throws Exception { //Instantiate a service object MasterDataService svc = new MasterDataService(); //We’ll use the default login provider (Fixed user and password) svc.setLoginProvider( new DefaultLoginProvider("hubuser","hubpw")); //We’ll use the default context provider also Properties props = new Properties(); svc.setContextProvider( new DefaultContextProvider("hubhost", 16000, props)); //The Bossof relationship represents a boss to employee relationship //Each boss can have zero to many employees //The boss is the "left" side of the relationship //The employee(s) are the "right" side of the relationship //We’ll find employee relationships for two boss identity entities IdentityEntityId ieid1 = new IdentityEntityId(305); IdentityEntityId ieid2 = new IdentityEntityId(343); //Create a list to hold the identifiers we’re looking for List ieidList = new ArrayList(); ieidList.add( ieid1); ieidList.add( ieid2); //Go get the employee relationships(s) for the given enterprise Ids from the service //The left side of the references the boss enterprise Ids //The input criteria is boss enterprise Ids, so search from the left List relationshipList = svc.searchBossofRelationshipFromLeft (ieidList); //Say how many we received System.out.println("Returned employees for " + relationshipList.size() + " boss enterprise Id(s)."); //Show the employee relationships for each boss enterprise Id for (int index = 0; index < relationshipList.size(); index++) { //Say which enterprise id we are looking at System.out.println("Employees for boss enterprise Id: " + ieidList.get(index); //Get the relationships for enterprise Id at the given index BossofRelationship[] relationships = relationshipList.get(index); if (relationships == null) { //No employees found for this boss enterprise Id. System.out.println("\tNo employees found."); } else { //Say how many employees we received for this boss enterprise Id. System.out.println("\tReturned " + relationships.length + " employees."); //Say which what employees this boss enterprise Id has for( BossofRelationship relationship: relationships ) { //Show the employee from the right side of the relationship System.out.println( "\t\tEmployee enterprise Id: " + relationship.getIdentityEntityIdRight()); } } } } }
In this code, you would replace the following items with values appropriate to your Master Data Engine: v v v v
hubuser - Username for your Master Data Engine. hubpw - Password for your Master Data Engine. hubhost - Host name or IP address for your Master Data Engine. 16000 - Port for your Master Data Engine.
Chapter 5. Creating a client using the Java API
27
With the above assumptions, your compile command would look like this: javac -d classes -cp dist/madclient.jar;lib/madapi2.jar JavaESOARelationshipExample.java
With the above assumptions, your run command would look like this: java -cp classes;dist/madclient.jar;lib/madapi2.jar;lib/commons-lang-2.4.jar; lib/commons-logging-1.1.1.jar;lib/commons-pool-1.4.jar;lib/madapi.jar; lib/madcommon.jar JavaESOARelationshipExample
The versions of the libraries may be different on your system. Use the versions that are located in the 'lib' subdirectory.
Additional code samples The following code samples are designed to help you get a better understanding of how the API is used to create client applications. LocationGet import com.initiate.client.*; import com.initiate.client.internal.*; import java.util.*; public class LocationGet { public static void main( String[] args) throws Exception { String cvwName = null; //Go get the person(s) from the service //Instantiate a service object MasterDataService svc = new MasterDataService(); //We’ll use the default login provider (Fixed user and password) svc.setLoginProvider( new DefaultLoginProvider("confidential","password")); //We’ll use the default context provider also Properties props = new Properties(); svc.setContextProvider( new DefaultContextProvider("localhost",16000, props)); //We’ll look up a specific person LocationId pid = new LocationId(); pid.setMemIdnum("1"); pid.setSrcCode("LOC"); //Create a list to hold the identifiers we’re looking for List idList = new ArrayList(); idList.add( pid); System.out.println("Input " + idList.size() + " person."); List locationList=svc.getLocationList(idList, cvwName, null, null); System.out.println("Returned " + locationList.size() + " person."); //Show their address for( Location location: locationList ) { for( Address name: location.getLocationAddressList() ) { System.out.println( name.getStLine1() + " " +name.getCity()); } } } }
LocationInsert
28
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
import com.initiate.client.*; import com.initiate.client.internal.*; import com.initiate.client.internal.BaseMasterDataService.UpdateMode; import java.util.*; public class LocationInsert { public static void main( String[] args) throws Exception { String cvwName = null; //Go get the person(s) from the service //Instantiate a service object MasterDataService svc = new MasterDataService(); //We’ll use the default login provider (Fixed user and password) svc.setLoginProvider( new DefaultLoginProvider("confidential","password")); //We’ll use the default context provider also Properties props = new Properties(); svc.setContextProvider( new DefaultContextProvider("localhost", 16000,props)); Location bean = new Location(); LocationId locationid = new LocationId(); locationid.setSrcCode("LOC"); List listOfAddress = new ArrayList(); Address addressList = new Address(); addressList.setStLine1("250 Brook Drive"); addressList.setStLine2("Green Park"); addressList.setCity("Reading "); addressList.setPostalCode("RG2 6UB"); listOfAddress.add(addressList); List listOfAttr = new ArrayList(); Memattr confirmedDocIdList = new Memattr(); confirmedDocIdList.setAttrVal("THIS IS THE DOCID"); listOfAttr.add(confirmedDocIdList); bean.setLocationId(locationid); bean.setLocationAddressList(listOfAddress); bean.setLocationDOCIDList(listOfAttr); UpdateMode mode = UpdateMode.AttrComp; Location locationReturnedId = svc.createOrUpdateLocation(bean, mode); System.out.println(locationReturnedId); LocationId returnedLocationid = locationReturnedId.getLocationId(); System.out.println("Inserted / Updated --> " + returnedLocationid.getSrcCode() + " : " + returnedLocationid.getMemIdnum()); } }
LocationSearch import com.initiate.client.*; import com.initiate.client.internal.*; import java.util.*; public class LocationSearch { public static void main( String[] args) throws Exception Chapter 5. Creating a client using the Java API
29
{ String cvwName = null; //Go get the person(s) from the service //Instantiate a service object MasterDataService svc = new MasterDataService(); //We’ll use the default login provider (Fixed user and password) svc.setLoginProvider( new DefaultLoginProvider("confidential","password")); //We’ll use the default context provider also Properties props = new Properties(); svc.setContextProvider( new DefaultContextProvider("localhost", 16000,props)); Location bean = new Location(); List listOfAddress = new ArrayList(); Address addressList = new Address(); addressList.setStLine1("1 The Peanut Road"); listOfAddress.add(addressList); bean.setLocationAddressList(listOfAddress); short minScore=0; int maxResults=100; List locationList=svc.searchLocationListAsLocation(bean, minScore, maxResults, cvwName, null, null); System.out.println("Returned " + locationList.size() + " Location."); if (locationList.size()>0) { //Show their address for( LocationSearchResult locationSearchResults: locationList ) { Location results = locationSearchResults.getLocation(); LocationId locationid = results.getLocationId(); System.out.println("Found --> " + locationid.getSrcCode() + " : " + locationid.getMemIdnum()); List addresses = results.getLocationAddressList(); for (Address address: addresses) { System.out.println("Found :" + address.getStLine1()); } } } else { System.out.println("NO RECORDS FOUND"); } } }
PersonGet import import import import import
com.initiate.client.*; com.initiate.client.Person.PersonAttribute; com.initiate.client.Person.PersonSource; com.initiate.client.internal.*; java.util.*;
public class PersonGet { public static void main( String[] args) throws Exception { String cvwName = null; PersonSource[] sources = null; PersonAttribute[] attributes = null; //Go get the person(s) from the service //Instantiate a service object MasterDataService svc = new MasterDataService(); //We’ll use the default login provider (Fixed user and password)
30
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
svc.setLoginProvider( new DefaultLoginProvider("confidential","password")); //We’ll use the default context provider also Properties props = new Properties(); svc.setContextProvider( new DefaultContextProvider("localhost", 16000, props)); //We’ll look up a specific person PersonId pid = new PersonId(); pid.setMemIdnum("1"); pid.setSrcCode("CONFIDENTIAL"); //Create a list to hold the identifiers we’re looking for List idList = new ArrayList(); idList.add( pid); System.out.println("Input " + idList.size() + " person."); List personList=svc.getPersonList(idList, cvwName, sources, attributes); System.out.println("Returned " + personList.size() + " person."); //Say how many we received for( Person person: personList ) { for( Memnameext name: person.getPersonNameList() ) { System.out.println( name.getOnmFirst() + " " +name.getOnmLast()); } } } }
PersonInsert import com.initiate.client.*; import com.initiate.client.internal.*; import com.initiate.client.internal.BaseMasterDataService.UpdateMode; import java.util.*; public class PersonInsert { public static void main( String[] args) throws Exception { String cvwName = null; //Go get the person(s) from the service //Instantiate a service object MasterDataService svc = new MasterDataService(); //We’ll use the default login provider (Fixed user and password) svc.setLoginProvider( new DefaultLoginProvider("confidential","password")); //We’ll use the default context provider also Properties props = new Properties(); svc.setContextProvider( new DefaultContextProvider("localhost", 16000,props)); Person bean = new Person(); PersonId personid = new PersonId(); personid.setSrcCode("CONFIDENTIAL"); personid.setMemIdnum("123456789"); List listOfAddress = new ArrayList(); Address addressList = new Address(); addressList.setStLine1("250 Brook Drive"); addressList.setStLine2("Green Park"); addressList.setCity("Reading "); addressList.setPostalCode("RG2 6UB");
Chapter 5. Creating a client using the Java API
31
listOfAddress.add(addressList); List listOfAttr = new ArrayList(); Memattr confirmedDocIdList = new Memattr(); confirmedDocIdList.setAttrVal("THIS IS THE DOCID"); listOfAttr.add(confirmedDocIdList); bean.setPersonId(personid); bean.setPersonAddressList(listOfAddress); bean.setConfirmedLinkDocIDList(listOfAttr); UpdateMode mode = UpdateMode.AttrComp; Person personReturnedId = svc.createOrUpdatePerson(bean, mode); System.out.println(personReturnedId); PersonId returnedPersonid = personReturnedId.getPersonId(); System.out.println("Inserted / Updated --> " + returnedPersonid.getSrcCode() + " : " + returnedPersonid.getMemIdnum()); } }
PersonSearch import com.initiate.client.*; import com.initiate.client.internal.*; import java.util.*; public class PersonSearch { public static void main( String[] args) throws Exception { String cvwName = null; //Go get the person(s) from the service //Instantiate a service object MasterDataService svc = new MasterDataService(); //We’ll use the default login provider (Fixed user and password) svc.setLoginProvider( new DefaultLoginProvider("confidential","password")); //We’ll use the default context provider also Properties props = new Properties(); svc.setContextProvider( new DefaultContextProvider("localhost", 16000,props)); Person bean = new Person(); List listofName = new ArrayList(); Memnameext nameList = new Memnameext(); nameList.setOnmLast("Meisels"); nameList.setOnmFirst("Michael"); listofName.add(nameList); bean.setPersonNameList(listofName); short minScore=0; int maxResults=100; List personList=svc.searchPersonListAsPerson(bean, minScore, maxResults, cvwName, null, null); System.out.println("Returned " + personList.size() + " Persons.");
32
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
if (personList.size()>0) { //Show their address for( PersonSearchResult personSearchResults: personList ) { Person results = personSearchResults.getPerson(); PersonId personid = results.getPersonId(); System.out.println(""); System.out.println("Found --> " + personid.getSrcCode() + " : " + personid.getMemIdnum()); List name = results.getPersonNameList(); for (Memnameext name1: name) { System.out.println("Name :" + name1.getOnmFirst() + " " + name1.getOnmLast()); } List addresses = results.getPersonAddressList(); for (Address address: addresses) { System.out.println("Address :" + address.getStLine1()); } } } else { System.out.println("NO RECORDS FOUND"); } } }
findPersonAddLocation import java.util.ArrayList; import java.util.List; import java.util.Properties; import com.initiate.client.*; import com.initiate.client.internal.*; import com.initiate.client.internal.BaseMasterDataService.UpdateMode; import java.util.*; public class findPersonAddLocation { public static void main(String[] args)throws Exception { String firstName = args[0]; String lastName = args[1]; String stline1 = args[2]; String stline2= args[3]; String stline3= args[4]; String stline4= args[5]; String city= args[6]; String postalcode= args[7]; String srcCode =""; String memidnum=""; String cvwName = null; //Go get the person(s) from the service //Instantiate a service object MasterDataService svc = new MasterDataService(); //We’ll use the default login provider (Fixed user and password) svc.setLoginProvider( new DefaultLoginProvider("confidential","password")); //We’ll use the default context provider also Properties props = new Properties(); Chapter 5. Creating a client using the Java API
33
svc.setContextProvider( new DefaultContextProvider("localhost", 16000,props)); Person bean = new Person(); List listofName = new ArrayList(); Memnameext nameList = new Memnameext(); nameList.setOnmLast(lastName); nameList.setOnmFirst(firstName); listofName.add(nameList); bean.setPersonNameList(listofName); short minScore=0; int maxResults=1; List personList=svc.searchPersonListAsPerson(bean, minScore, maxResults, cvwName, null, null); System.out.println("Returned " + personList.size() + " Persons."); for( PersonSearchResult personSearchResults: personList ) { Person results = personSearchResults.getPerson(); PersonId personid = results.getPersonId(); System.out.println(""); System.out.println("Found --> " + personid.getSrcCode() + " : " + personid.getMemIdnum()); List name = results.getPersonNameList(); for (Memnameext name1: name) { System.out.println("Name :" + name1.getOnmFirst() + " " + name1.getOnmLast()); } List addresses = results.getPersonAddressList(); for (Address address: addresses) { System.out.println("Address :" + address.getStLine1()); } srcCode = personid.getSrcCode(); memidnum = personid.getMemIdnum(); } if ((srcCode != "") && (memidnum !="")) { Address addressList = new Address(); addressList.setStLine1(stline1); addressList.setStLine2(stline2); addressList.setStLine3(stline3); addressList.setStLine4(stline4); addressList.setCity(city); addressList.setPostalCode(postalcode); if (addAddress(svc,srcCode,memidnum,addressList)) { if (addLocation(svc,srcCode,memidnum,addressList)) System.out.println("Operation Completed Successfully"); } } } private static boolean addLocation(MasterDataService svc, String srcCode, String memidnum, Address addressList) { Location bean = new Location();
34
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
LocationId locationid = new LocationId(); locationid.setSrcCode("LOC"); List listOfAddress = new ArrayList(); listOfAddress.add(addressList); List listOfAttr = new ArrayList(); Memattr confirmedDocIdList = new Memattr(); confirmedDocIdList.setAttrVal(srcCode+"|"+memidnum); listOfAttr.add(confirmedDocIdList); bean.setLocationId(locationid); bean.setLocationAddressList(listOfAddress); bean.setLocationDOCIDList(listOfAttr); UpdateMode mode = UpdateMode.AttrComp; Location locationReturnedId; try { locationReturnedId = svc.createOrUpdateLocation(bean, mode); System.out.println(locationReturnedId); LocationId returnedLocationid = locationReturnedId.getLocationId(); System.out.println("Inserted / Updated --> " + returnedLocationid.getSrcCode() + " : " + returnedLocationid.getMemIdnum()); return true; } catch (MasterDataServiceException e) { // TODO Auto-generated catch block e.printStackTrace(); } return false; } private static boolean addAddress(MasterDataService svc, String srcCode, String memidnum, Address addressList) { // TODO Auto-generated method stub Person bean = new Person(); PersonId personid = new PersonId(); personid.setSrcCode(srcCode); personid.setMemIdnum(memidnum); List listOfAddress = new ArrayList(); listOfAddress.add(addressList); List listOfAttr = new ArrayList(); Memattr confirmedDocIdList = new Memattr(); confirmedDocIdList.setAttrVal(srcCode+"|"+memidnum); listOfAttr.add(confirmedDocIdList); bean.setPersonId(personid); bean.setPersonAddressList(listOfAddress); bean.setConfirmedLinkDocIDList(listOfAttr); UpdateMode mode = UpdateMode.AttrComp; Person personReturnedId; try { personReturnedId = svc.createOrUpdatePerson(bean, mode); System.out.println(personReturnedId); Chapter 5. Creating a client using the Java API
35
PersonId returnedPersonid = personReturnedId.getPersonId(); System.out.println("Inserted / Updated --> " + returnedPersonid.getSrcCode() + " : " + returnedPersonid.getMemIdnum()); return true; } catch (MasterDataServiceException e) { // TODO Auto-generated catch block e.printStackTrace(); } return false; } }
36
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
Chapter 6. Creating a client using the web services About this task The client application you will write is 100% customized for your particular implementation, and so no two applications will be identical. In our example, we will demonstrate how to access the deployed web service from a client program written in Java. Our example Hub was configured using a member type called Person, which has two entities, identity and household. The web services API can be invoked in a number of ways from different programming languages. The contract for the web services is completely defined by the WSDL (web services Description Language). The WSDL file is an XML file that describes the data types and available operations for a service. The WSDL for the IBM Initiate Enterprise Service Oriented Architecture (ESOA) Toolkit can be found statically in the ISI_Client_9.7. x .zip distribution generated by IBM Initiate Workbench or dynamically from a server with the deployed madclient.war: http://[server]:[port]/madclient/services/mds?wsdl
When consuming the web services from Java the client has a number of options. Examples include: v JAX-WS (included with Java 6, available as a library package for Java 5)) v http://cxf.apache.org/Apache CXF v Axis2 The recommended ways of consuming the web services from Java are to use either a pure generated JAX-WS client (based entirely on the WSDL, no third party libraries required) or a CXF client that leverages the ESOA classes generated by IBM Initiate Workbench (madclient.jar – similar coding syntax to a pure Java client). The web services can also be consumed from Microsoft .NET. To invoke the web services using a graphical tool, try soapUI. See “Using soapUI to invoke the web services” on page 41. Additional examples can be found in “Examples” on page 39.
Creating the web service client Before you begin Ensure that: v You are using a supported version of the Java SDK (refer to the IBM Initiate Master Data Service System Requirements) v You have deployed the madclient.war to an application server. Here we'll assume the following: The host serving the application is myhost The port serving the application is 8080 The application context is madclient © Copyright IBM Corp. 1995, 2011
37
About this task The following steps will guide you through the process of creating a web service client application.
Procedure 1. Start in a working directory. Create subdirectories to hold generated Java source files and compiled class files. We will call these subdirectories src and classes. 2. Determine the URL to obtain the WSDL from the application. With the assumptions above, the URL would be: http://myhost:8080/madclient/ services/mds?wsdl Substitute other appropriate values for myhost, 8080 and madclient. The rest of the URL will be the same. You can also find the WSDL in the generated ISI_Client_9.7. x .zip file located at \workspace\project_name\client. 3. Use the wsimport tool provided with Sun Microsystem's Java SDK to obtain Java classes from the WSDL provided by the application. wsimport -d classes -s src -p myclient http://myhost:8080/madclient/ services/mds?wsdl Here we have chosen to place the generated classes into a package named myclient. You can choose whatever name you like for this package. 4. Write Java code to access the web service.
Login provider The Login Provider specifies how user credentials are passed from the client to the web services. The web services then use these credentials to invoke interactions with the Master Data Engine.
How to configure the login provider If either the HttpBasicAuthLoginProvider or the WSSecurityUsernameTokenPasswordTextLoginProvider is configured, the client code that invokes the web service must pass the credentials in the required manner (see examples below). To configure the Login Provider, add the following line(s) into the madclient.properties file for on the web server: DefaultLoginProvider: All clients and interactions use the specified username and password. loginProvider.username=system loginProvider.password=system loginProvider.classname=com.initiate.client.internal.DefaultLoginProvider
HttpBasicAuthLoginProvider: The client passes the user credentials along with the web service request in the HTTP header. Note: The loginProvider.username and loginProvider.password should NOT be specified. loginProvider.classname=com.initiate.client.internal.HttpBasicAuthLoginProv ider
WSSecurityUsernameTokenPasswordTextLoginProvider: The client passes the user credentials along with the web service request in the SOAP header.
38
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
Note: The loginProvider.username and loginProvider.password should NOT be specified. loginProvider.classname=com.initiate.client.internal.WSSecurityUsernameToke nPasswordTextLoginProvider
Creating the soapUI HTTP Basic Auth header About this task soapUI supports adding custom HTTP headers into the web service request. Unfortunately, it does not have built in support for HTTP Basic Auth. The user must create the header manually.
Procedure 1. In the Request window, select the “Headers” tab on the bottom left. 2. Click the “+” button to add a header. The name of the header must be “Authorization.” Click OK. 3. In the value box, enter the word “Basic” plus the base64-encoded username:password. Use a base 64 encoder/decoder tool to create the base64 user:password string. For example, the Base64 version of “testuser:testpwd” is “dGVzdHVzZXI6dGVzdHB3ZA==” so the Value for the header would be Basic dGVzdHVzZXI6dGVzdHB3ZA==
Configuring soapUI WS-Security About this task soapUI has built-in support for WS-Security SOAP headers.
Procedure 1. In the Request Propeties box in the lower left hand corner, enter the appropriate values in the Username and Password properties. 2. Select PasswordText for the WSS-Password Type property.
Examples For this example, we have a member type called Person, and a Person has a LegalName attribute with fields for first and last name. A Person can be identified by a number assigned by source MYSRC. import myclient.*; import java.util.*; public class ESOAWebServicesExample { public static void main( String[] args) throws Exception { //Get a handle to the web service MasterDataWebServiceService ssvc = new MasterDataWebServiceService(); //Get a proxy for the specific port we want to use MasterDataWebService svc = ssvc.getMasterDataWebServicePort(); //We’ll look up one specific person PersonId pid = new PersonId(); pid.setMemIdnum("55555"); pid.setSrcCode("MYSRC"); //Create a list to hold the identifiers we’re looking for List pidList = new ArrayList(); pidList.add( pid); Chapter 6. Creating a client using the web services
39
//Go get the person(s) from the service List personList = svc.getPersonList( pidList, null, null, null); //Say how many we received System.out.println("Returned " + personList.size() + " person(s)."); //Show their names for( Person person: personList ) { for( Memname name: person.getLegalNameList().getLegalName() ) { System.out.println( name.getOnmFirst() + " " + name.getOnmLast()); } } } }
How to use the generated JAX-WS client stubs The stub classes generated by the wsimport tool must be compiled and added to the class path. import com.initiate.demo.ws.MasterDataWebService; import com.initiate.demo.ws.MasterDataWebServiceService; public class ESOAClientJaxWs { public static void main(String[] args) { MasterDataWebServiceService ssvc = new MasterDataWebServiceService(); MasterDataWebService svc = ssvc.getMasterDataWebServicePort(); //... perform operation(s) using the srv... } }
How to use the generated API classes (madclient.jar) with CXF Add all of the lib jars from the CXF distribution to the class path along with the madclient.jar and lib jars from the ISI_Client_9.7. x .zip distribution file generated by IBM Initiate Workbench. import java.net.URL; import javax.xml.namespace.QName; import javax.xml.ws.Service; import com.initiate.client.MasterDataWebService; public class ESOAClientCxf { public static void main(String[] args) throws Exception { URL wsdlURL = new URL("http://localhost:8080/madclient/services/mds?wsdl"); QName SERVICE_NAME = new QName("http://client.initiate.com/", "MasterDataWebServiceService"); Service service = Service.create(wsdlURL, SERVICE_NAME); MasterDataWebService svc = service.getPort(MasterDataWebService.class); //... perform operation(s) using the svc... } }
How to use the C# Microsoft .NET client stubs The following code sample is designed to help you understand how to use the C# Microsoft .NET client stubs. using using using using
40
System; System.Collections.Generic; System.Text; ESOADemo.esoa;
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
namespace ESOADemo { class Program { static void Main(string[] args) { MasterDataWebServiceService mds = new MasterDataWebServiceService(); personId[] idList = new personId[1]; personId id = new personId(); id.srcCode = "RMC"; id.memIdnum = "870504"; idList[0] = id; string cvwName = null; personSource[] sourceFilter = null; personAttribute[] attributeFilter = null; person[] results = mds.getPersonList(idList, cvwName, sourceFilter, attributeFilter); } } }
Using soapUI to invoke the web services About this task soapUI is a simple tool that can be used to invoke the web services without writing code.
Procedure 1. Install and run soapUI. 2. Create a new soapUI project. 3. In the “Initial WSDL/WADL” box, enter the URL of the ESOA web services and click OK. This will generate a tree in the Navigator pane containing all the methods on the service. v To invoke a method, click the [+] icon to expand the method name and show the default request file. v Double-click the request to edit the criteria. 4. Remove any unused elements and make sure that all of the “?” placeholders are removed as well. 5. Invoke the service method using the specified request XML by clicking the green arrow button.
Results Below is a sample request XML for the “searchPersonListAsIdentity” method (record type Person, entity type Identity): Patty Countryman Chapter 6. Creating a client using the web services
41
1 10
42
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
Chapter 7. RESTful services The acronym REST stands for Representational State Transfer, a methodology in which each unique URL is a representation of an object. You can access and manipulate the object using HTTP operations: GET to retrieve it, DELETE to delete it, POST to create it, or PUT to update it. REST is becoming more and more popular across many types of businesses because of its strong advantages: v Lightweight - requests and responses can be short and require less bandwidth v Human readable results v Easy to build - there is less reliance on toolkits v Concise - no need for additional messaging layer However, REST is not ideal in certain scenarios, such as when you need to include secure data in a request. Which method is best depends on the needs of your client application and its users. For more information on REST vs. SOAP, consult a third-party text. The following operations are supported: v search and retrieve member and relationship data (memsearch, memget, relsearch, relget) v edit, add and delete member and relationship data (memput, memputqual, relput, memdelete, memundelete, reldelete, memdrop) v undo recent put, merge or delete record operations (MEMUNDO) v compare and score member data (memcompare, memscore) v merge and unmerge member records (memmerge, memunmerge) v member, entity, attribute and field labels v member attribute order v member, entity and attribute display templates v member and entity default composite views The operations supported are listed in the REST Services Documentation. See “Accessing the documentation” on page 50 for detailed information.
Installing the service layer Users who wish to leverage an existing application server can do so by following the configuration and deployment steps for the stand-alone REST server.
About this task Before you can get started using the RESTful services, set up your environment as follows: v Install the engine and configure a Hub instance. See IBM Initiate Master Data Service Engine Installation Guidefor instructions. If you wish to use the embedded REST server, choose the option to install the Application Services. v If the embedded REST server was not installed during Hub instance creation (madconfig), install a stand-alone web application server, such as Apache Tomcat, Oracle WebLogic Server or IBM WebSphere Application Server.
© Copyright IBM Corp. 1995, 2011
43
Configuring the embedded REST server This mode requires very little configuration since application services are provided via a web server that is hosted inside the Master Data Engine's process space. If you use the embedded REST server, use a plain text editor to edit the hub_instance_path\inst\mpinet_ hub_instance_name \conf\ com.initiate.server.appsvcs.cfg file to set the following properties as needed to suit your environment (default values are shown): loginProvider.classname=com.initiate.client.internal.HttpBasicAuthLoginProvider loginProvider.username= loginProvider.password= serviceMetaData.memstat=A,O serviceMetaData.recstat=A contextPool.maxSize=2 contextPool.maxWaitMillis=0
Table 4 explains each property. Adjust values as needed to suit your environment. Table 4. Supported embedded REST server runtime properties Property
Description
loginProvider.classname
The class name of the login provider to be used by the web service. The choices are: v com.initiate.client.internal.DefaultLoginProvider - Use this provider if you are using a stand-alone web application server and want all users of the web service to access the Master Data Engine using a fixed username. v com.initiate.client.internal.HttpBasicAuthLoginProvider Use this provider if you are using the embedded web application server and want the username/password for the Master Data Engine to be provided by the web service client. The client must provide the username/password using the HTTP Basic Authentication method. The loginProvider.username/password properties should not be set since every HTTP request will have its HTTP headers interrogated for username/password information. Default: com.initiate.client.internal.HttpBasicAuthLoginProvider
loginProvider.username
This is the username used to log into the Master Data Engine. It should only be used with the DefaultLoginProvider (stand-alone web server). Default: none
loginProvider.password
This is the password used to log into the Master Data Engine. It should only be used with the DefaultLoginProvider (stand-alone web server). Default: none
serviceMetaData.memstat The serviceMetaData.memstat property filters results by member status. You can specify multiple values separated by commas. Valid member status values are Active (A), Overlay (O), Merged (M), Deleted (D) and Fictitious (F). This value can also be set programmatically during Search or Get operations. If you supply a memstat on the RESTful call, it will override the global default only for that call. Default: A,O
44
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
Table 4. Supported embedded REST server runtime properties (continued) Property
Description
serviceMetaData.recstat
The serviceMetaData.recstat property filters results by record status. Although optional, no attributes (only memHead records) will be returned if this is not set. Typically you would want to get at least 'A'ctive attributes. You can select multiple status codes in the dialog box. Valid values are Active (A), Inactive (I), Deleted (D) and Shadow (S). You can specify multiple values separated by commas. This value can also be set programmatically during Search or Get operations. If you supply a recstat on the RESTful call, it will override the global default only for that call. Default: A
contextPool.maxSize
The maximum number of contexts to create. Default: 2
contextPool.maxWait Millis
The length of time (in milliseconds) to wait for a context to become available before returning an error. Default: 0
The port number of the embedded web server is identified by the port property within the file: hub_instance_path\inst\mpinet_hub_instance_name\conf\com.initiate.server.web.cfg
If the Hub instance is currently running, restart it. You are now ready to start building client applications.
Enabling SSL on the internal Jetty web server You can enable SSL on the embedded web server by setting the useSSL flag to true.
About this task The following steps will guide you through the process of enabling SSL on the embedded web server.
Procedure 1. Open the hub_instance_path\inst\mpinet_hub_instance_name\conf\ com.initiate.server.web.cfg file in a plain text editor. 2. Set the useSSL flag to true. 3. Optional: You can change the HTTPS port by setting the port property. The default HTTPS port is 443. 4. Optional: Custom keystore/truststore properties can be changed within the com.initiate.server.web.cfg file. 5. Restart the Hub instance once the desired changes have been made.
Configuring the stand-alone application server Stand-alone mode refers to deploying a web application onto a third-party application server. Properties such as the login provider or Master Data Engine host name and port are specified in the madappsvcs.properties file.
Chapter 7. RESTful services
45
About this task Create the madappsvcs.properties file by following the steps below.
Procedure 1. Create a new text file called madappsvcs.properties. 2. Type (or copy and paste) the following text into the madappsvcs.properties file: loginProvider.classname=com.initiate.client.internal.DefaultLoginProvider loginProvider.username=system loginProvider.password=system serviceMetaData.memstat=A,O serviceMetaData.recstat=A contextFactory.hostName=localhost contextFactory.hostPort=16000 contextFactory.useSSL=false contextFactory.secLib=SSL contextFactory.sslVersion=SSLv3 contextFactory.sslCertVerify=false contextPool.initialSize=0 contextPool.maxSize=2 contextPool.maxWaitMillis=0 adminLoginProvider.classname=com.initiate.client.internal.DefaultLoginProvider adminLoginProvider.username=system adminLoginProvider.password=system adminLoginProvider.passwordScheme=plain adminLoginProvider.pwd3.aeskeyfile= adminLoginProvider.pwd3.aesivfile= adminLoginProvider.pwd3.aesprovider=
Adjust values as needed to suit your environment. Table 5 on page 47explains each property. 3. Navigate to the hub_install_path\lib\sdk\madappsvcs.war file. 4. Create the subdirectory WEB-INF\classes. 5. Place the madappsvcs.properties file in WEB-INF\classes. 6. On the command line, use the command jar uf madappsvcs.war WEB-INF\classes\madappsvcs.properties to embed the properties file in the war file. Alternatively, you could place the madappsvcs.properties file in a common location accessible by the web application server. Refer to the application server documentation for instructions. 7. Deploy the madappsvcs.war file to your application server.
Supported stand-alone REST server runtime properties Stand-alone mode refers to deploying a web application onto a third-party application server. You can configure the REST server in stand-alone mode using the supported runtime properties.
46
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
Table 5. Supported stand-alone REST server runtime properties Property
Description
loginProvider.classname
The class name of the login provider to be used by the web service. The choices are: v com.initiate.client.internal.DefaultLoginProvider Use this provider if you are using a stand-alone web application server and want all users of the web service to access the Master Data Engine using a fixed username. The loginProvider.username and loginProvider.password properties must be specified and all RESTful calls will be using that username/password without having to pass authentication with every HTTP request. v com.initiate.client.internal.HttpBasicAuth LoginProvider - Use this provider if you are using the embedded web application server and want the username/password for the Master Data Engine to be provided by the web service client. The client must provide the username/password using the Http Basic Authentication method. Default: com.initiate.client.internal.DefaultLoginProvider
loginProvider.username
This is the username used to log into the Master Data Engine. Default: none
loginProvider.password
This is the password used to log into the Master Data Engine. Default: none
serviceMetaData.memstat
The serviceMetaData.memstat property filters results by member status. You can specify multiple values separated by commas. Valid member status values are Active (A), Overlay (O), Merged (M), Deleted (D) and Fictitious (F). This value can also be set programmatically during Search or Get operations. If you supply a memstat on the RESTful call, it will override the global default only for that call. Default: A,O
serviceMetaData.recstat
The serviceMetaData.recstat property filters results by record status. Although optional, no attributes (only memHead records) will be returned if this is not set. Typically you would want to get at least 'A'ctive attributes. You can select multiple status codes in the dialog box. Valid values are Active (A), Inactive (I), Deleted (D) and Shadow (S). You can specify multiple values separated by commas. You can specify multiple values separated by commas. This value can also be set programmatically during Search or Get operations. If you supply a recstat on the RESTful call, it will override the global default only for that call. Default: A
Chapter 7. RESTful services
47
Table 5. Supported stand-alone REST server runtime properties (continued) Property
Description
contextFactory.hostName
This is the name (or IP address) of the host running the Master Data Engine. Default: localhost
contextFactory.hostPort
This is the network port number for the Master Data Engine. Default: 16000
contextFactory.useSSL
This is true if communication with Master Data Engine is encrypted. Default: false
contextFactory.secLib
Used only if useSSL is true. This property is applicable to the stand-alone application servers only. Default: SSL
contextFactory.sslVersion
Used only if useSSL is true. This property is applicable to the stand-alone application servers only. Default: SSLv3
contextFactory.sslCertVerify
Used only if useSSL is true. This property is applicable to the stand-alone application servers only. Default: false
contextPool.initialSize
The number of contexts to create on web application startup. This property is applicable to the stand-alone application servers only. Default: 0
contextPool.maxSize
The maximum number of contexts to create. Default: 2
contextPool.maxWaitMillis
The length of time (in milliseconds) to wait for a context to become available before returning an error. Default: 0
adminLoginProvider.classname
Identifies the class that is used to "bootstrap" the metadata within a stand-alone deployment of the RESTFUL web application. This value should not be modified. Default: com.initiate.client.internal.DefaultLoginProvider
adminLoginProvider.username
Identifies a user who has at least read-only access to all dictionary segments. Default: system
adminLoginProvider.password
Identifies the password for the adminLoginProvider.username. Default: system
48
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
Table 5. Supported stand-alone REST server runtime properties (continued) Property
Description
adminLoginProvider.password Scheme
The following values are valid for this property: "plain", "pwd2", and "pwd3." Default: plain
adminLoginProvider.pwd3. aeskeyfile
The full path and name of the AES key file in hex encoded format for the RESTful services. This property is required if the passwordScheme is set to "pwd3." Default: none
adminLoginProvider.pwd3. aesivfile
The full path and name of the AES IV file in hex encoded format for the RESTful services. This property is required if the passwordScheme is set to "pwd3." Default: none
adminLoginProvider.pwd3. aesprovider
The JSSE/JCE AES cipher provider for the RESTful services. This property is required if the passwordScheme is set to "pwd3." Default: none
The IBM Initiate Flexible Search REST API For full details of the REST API, see the online REST documentation at the URL http://yourhost:7378/madappsvcs.
Terms The textSearchForTermList method performs a search for terms that match the provided field name and prefix. To search for terms, perform a GET from the URL http://yourhost:7378/ madappsvcs/rest/text/terms. Specify the fieldName, prefix and maxResults using query parameters. The method returns a TermSearchResult object.
Search returning members The textSearchForRecordList method performs a full text search for records that match the criteria in the provided query string. Matched records are retrieved using ASMEMBER get semantics. To perform a search that returns member records, POST the query to the URL http://yourhost:7378/madappsvcs/rest/text/record. The only mandatory query parameter is entType. The method returns a GenericTextSearchResult object.
Search returning entities The textSearchForEntitiesList method performs a full text search for entities that match the criteria in the provided query string. Matched records are retrieved using ASENTITY get semantics. You can perform a search that returns entity information by POSTing the query to the URL http://yourhost:7378/madappsvcs/rest/text/entity. The only mandatory query parameter is entType. All of the optional parameters described for the member search also apply to the entity search. Chapter 7. RESTful services
49
The method returns a GenericEntitySearchResult object.
Accessing the documentation Before you can begin creating the client applications, you'll need to know which objects you can access and manipulate and which HTTP verb(s) you can call. To access the RESTdoc, go to the following URL: http://server:port/madappsvcs/
For example: http://localhost:7378/madappsvcs/
Client application headers The base URI for the web service is http://server:port/madappsvcs/. The objects' paths shown in the RESTdoc are relative to this application root. Authentication is provided via HTTP headers. The IBM Initiate REST services accept the following MIME headers: v Accept header - the format the client would like returned v Content-Type header - the format in which the client is passing data We support XML and JSON only. Valid types for the headers are: v XML: application/xml and text/xml v JSON: application/json and text/json Instead of sending in the Accept or Content-Type headers, the type can also be specified on the URL, for example: http://localhost:7378/madappsvcs/rest/record/RMC/4567.json/
The .json or .xml extension must follow the last element in the URL.
Example of a client application Now that you have it installed and configured, and you know where to find the RESTdoc, we will walk through creating a sample application. This HTML form retrieves the core system metadata:
Simple http request using an html form:
Submit
For all other REST services, authentication has to be provided via HTTP headers. In most cases, you will probably want to use a proxy server to handle the request, although using a thirdy party tool such as cURL (http://groups.csail.mit.edu/cag/ curl/) is another option. Configuring a proxy server is outside the scope of this document, therefore, the following example shows how to execute the command using cURL. This command performs a simple MEMGET operation.
50
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
curl --request GET --url "http://hubserver:7378/madappsvcs/rest/record/RMC/558090.json" --header "Content-Type: application/json" --header "Authorization: Basic dGVzdHVzZXI6dGVzdHBhc3N3b3Jk"
This example is submitting a getRecord request where the source is RMC and the memIDnum is 558090, returned in JSON format. The authentication header is username:password encoded with Base64 encoding, therefore for this example, the username/password was testuser:testpassword.
Chapter 7. RESTful services
51
52
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
Appendix. Troubleshooting The Enterprise Services component provides logging capabilities for aid in diagnosing problems. Logging is implemented using the Apache Commons Logging framework. See http://commons.apache.org/logging for more information. The logging category to enable is com.initiate.client. Information is logged at the Debug and Trace levels.
© Copyright IBM Corp. 1995, 2011
53
54
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
Legal Statement Licensed Materials – Property of IBM © Copyright IBM Corporation, 1995, 2011. US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. IBM, the IBM logo, Initiate, and Initiate Master Data Service are trademarks of IBM Corp., registered in many jurisdictions worldwide. Java and all Java-based trademarks and logos are trademarks or registered trademarks of Oracle and/or its affiliates. Other product and service names might be trademarks of IBM, or other companies. This Program is licensed under the terms of the license agreement accompanying the Program. This license agreement may be either located in a Program directory folder or library identified as "License" or "Non-IBM License", if applicable, or provided as a printed license agreement. Please read this agreement carefully before using the Program. By using the Program, you agree to these terms.
© Copyright IBM Corp. 1995, 2011
55
56
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
Notices and trademarks This information was developed for products and services offered in the U.S.A.
Notices IBM may not offer the products, services, or features discussed in this document in other countries. Consult your local IBM representative for information on the products and services currently available in your area. Any reference to an IBM product, program, or service is not intended to state or imply that only that IBM product, program, or service may be used. Any functionally equivalent product, program, or service that does not infringe any IBM intellectual property right may be used instead. However, it is the user's responsibility to evaluate and verify the operation of any non-IBM product, program, or service. IBM may have patents or pending patent applications covering subject matter described in this document. The furnishing of this document does not grant you any license to these patents. You can send license inquiries, in writing, to: IBM Director of Licensing IBM Corporation North Castle Drive Armonk, NY 10504-1785 U.S.A. For license inquiries regarding double-byte character set (DBCS) information, contact the IBM Intellectual Property Department in your country or send inquiries, in writing, to: Intellectual Property Licensing Legal and Intellectual Property Law IBM Japan Ltd. 1623-14, Shimotsuruma, Yamato-shi Kanagawa 242-8502 Japan The following paragraph does not apply to the United Kingdom or any other country where such provisions are inconsistent with local law: INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS PUBLICATION "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Some states do not allow disclaimer of express or implied warranties in certain transactions, therefore, this statement may not apply to you. This information could include technical inaccuracies or typographical errors. Changes are periodically made to the information herein; these changes will be incorporated in new editions of the publication. IBM may make improvements and/or changes in the product(s) and/or the program(s) described in this publication at any time without notice. Any references in this information to non-IBM Web sites are provided for convenience only and do not in any manner serve as an endorsement of those Web
© Copyright IBM Corp. 1995, 2011
57
sites. The materials at those Web sites are not part of the materials for this IBM product and use of those Web sites is at your own risk. IBM may use or distribute any of the information you supply in any way it believes appropriate without incurring any obligation to you. Licensees of this program who wish to have information about it for the purpose of enabling: (i) the exchange of information between independently created programs and other programs (including this one) and (ii) the mutual use of the information which has been exchanged, should contact: IBM Corporation J46A/G4 555 Bailey Avenue San Jose, CA 95141-1003 U.S.A. Such information may be available, subject to appropriate terms and conditions, including in some cases, payment of a fee. The licensed program described in this document and all licensed material available for it are provided by IBM under terms of the IBM Customer Agreement, IBM International Program License Agreement or any equivalent agreement between us. Any performance data contained herein was determined in a controlled environment. Therefore, the results obtained in other operating environments may vary significantly. Some measurements may have been made on development-level systems and there is no guarantee that these measurements will be the same on generally available systems. Furthermore, some measurements may have been estimated through extrapolation. Actual results may vary. Users of this document should verify the applicable data for their specific environment. Information concerning non-IBM products was obtained from the suppliers of those products, their published announcements or other publicly available sources. IBM has not tested those products and cannot confirm the accuracy of performance, compatibility or any other claims related to non-IBM products. Questions on the capabilities of non-IBM products should be addressed to the suppliers of those products. All statements regarding IBM's future direction or intent are subject to change or withdrawal without notice, and represent goals and objectives only. This information is for planning purposes only. The information herein is subject to change before the products described become available. This information contains examples of data and reports used in daily business operations. To illustrate them as completely as possible, the examples include the names of individuals, companies, brands, and products. All of these names are fictitious and any similarity to the names and addresses used by an actual business enterprise is entirely coincidental. COPYRIGHT LICENSE: This information contains sample application programs in source language, which illustrate programming techniques on various operating platforms. You may copy, modify, and distribute these sample programs in any form without payment to
58
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
IBM, for the purposes of developing, using, marketing or distributing application programs conforming to the application programming interface for the operating platform for which the sample programs are written. These examples have not been thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability, serviceability, or function of these programs. The sample programs are provided "AS IS", without warranty of any kind. IBM shall not be liable for any damages arising out of your use of the sample programs. Each copy or any portion of these sample programs or any derivative work, must include a copyright notice as follows: © (your company name) (year). Portions of this code are derived from IBM Corp. Sample Programs. © Copyright IBM Corp. _enter the year or years_. All rights reserved. If you are viewing this information softcopy, the photographs and color illustrations may not appear.
Trademarks IBM, the IBM logo, and ibm.com are trademarks or registered trademarks of International Business Machines Corp., registered in many jurisdictions worldwide. Other product and service names might be trademarks of IBM or other companies. A current list of IBM trademarks is available on the web at "Copyright and trademark information" at www.ibm.com/legal/copytrade.shtml. The following terms are trademarks or registered trademarks of other companies: Adobe is a registered trademark of Adobe Systems Incorporated in the United States, and/or other countries. Linux is a registered trademark of Linus Torvalds in the United States, other countries, or both. Microsoft, Windows, and Windows NT are trademarks of Microsoft Corporation in the United States, other countries, or both. UNIX is a registered trademark of The Open Group in the United States and other countries. Java and all Java-based trademarks and logos are trademarks or registered trademarks of Oracle and/or its affiliates.
Notices and trademarks
59
60
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
Index A adding generated code to class path application server considerations WebLogic 21 WebSphere 21 architecture 1 authentication 9
R
examples (continued) PoolContextProvider 24 pre/post usage 9 retrieving records 25 retrieving relationships 26 web service 39
2
RESTful services 43 runtime properties 19
S
G C
generated API classes 40 generating code 14 generation utility 13
callout handlers 7, 9 class path adding generated ESOA source code 16 Java 14 classes context providers 24 GenericMasterDataService 8, 25 LoginProvider 24 MasterDataServiceImpl 15 MasterDataWebService 15 client application headers 50 client stubs C++ .NET 40 JAX-WS 40 compiling 16 creating a client Java 23 web services 37 creating the Java client 23 creating the web services client 38 customer support contacting 63 customizing object names 4 customizing the API 3
H HttpBasicAuthLoginProvider
J Java API creating the client generating 13 JSON 50
L
T
legal notices 57 library paths 15 login provider 24, 38
trademarks list of 57 troubleshooting Apache Commons Logging framework 53
M mapping methods 7 mapping overview 9 MasterDataLoginProvider 24 MasterDataServiceImpl 15 MasterDataWebService 15
D DefaultContextProvider 24 DefaultLoginProvider 38 deploy the WAR 21 documentation accessing the Javadoc Information RESTdoc 50
23
next steps
embedded REST server configuring 44 enabling SSL 45 ESOA API creating callout handlers extending 14 extensibility options 3 generating 13 examples additional 28 client application 50 EntMng usage 10
7
© Copyright IBM Corp. 1995, 2011
user credentials
9
web services creating the client 38 deploying 19 deploying the WAR file 21 example 39 generating 13 runtime properties 19, 20 using soap UI to invoke 41 WebLogic considerations 21 WebSphere considerations 21 WSSecurityUsernameTokenPasswordTextLoginProvider
17
O E
U W
N 14
38
service layer 43 sL enabling in embedded REST server 45 soapUI configuring web services security 39 HTTP basic auth header 39 invoking web service 41 software services contacting 63 stand-alone REST server configuring 46 supported runtime properties 47 stubs C++ .NET 40 JAX-WS 40 support customer 63
object names 4 overview architecture 1 basics 1 getting started 2 introduction v, 1 system requirements
v
X XML
P packaging 16 PoolContextProvider property map 5
50
24
61
38
62
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
Contacting IBM You can contact IBM for customer support, software services, product information, and general information. You also can provide feedback to IBM about products and documentation. The following table lists resources for customer support, software services, training, and product and solutions information. Table 6. IBM resources Resource
Description and location
IBM Support Portal
You can customize support information by choosing the products and the topics that interest you at www.ibm.com/support/ entry/portal/Overview/Software/ Information_Management/IBM Initiate_Master_Data_Service
Software services
You can find information about software, IT, and business consulting services, on the solutions site at www.ibm.com/ businesssolutions/
My IBM
You can manage links to IBM web sites and information that meet your specific technical support needs by creating an account on the My IBM site at www.ibm.com/account/
Training and certification
You can learn about technical training and education services designed for individuals, companies, and public organizations to acquire, maintain, and optimize their IT skills at http://www.ibm.com/software/swtraining/
IBM representatives
You can contact an IBM representative to learn about solutions at www.ibm.com/connect/ibm/us/en/
Providing feedback The following table describes how to provide feedback to IBM about products and product documentation. Table 7. Providing feedback to IBM Type of feedback
Action
Product feedback
You can provide general product feedback through the Consumability Survey at www.ibm.com/software/data/info/ consumability-survey
© Copyright IBM Corp. 1995, 2011
63
Table 7. Providing feedback to IBM (continued) Type of feedback
Action
Documentation feedback
To comment on the information center, click the Feedback link on the top right side of any topic in the information center. You can also send comments about PDF file books, the information center, or any other documentation in the following ways: v Online reader comment form: www.ibm.com/software/data/rcf/ v E-mail:
[email protected]
64
Enterprise Services-Oriented Architecture (ESOA) Toolkit User's Guide
Printed in USA
SC19-3148-01