Implementing the OpenEdge Reference Architecture John Sadd Progress Fellow and OpenEdge Evangelist Agenda Simplify your business 2 Introducing the OERA Implementation Business Entities and Data Access Objects Business Logic Issues Introducing the Service Interface Layer Managing ProDataSet instances Context Management Conclusions © 2005 Progress Software Corporation Implementing the OERA Modern Application Architecture OpenEdge Reference Architecture – a layered view Enterprise Services Users Separated presentation and integration layers Presentation Layer Simplify your business Common business logic with advanced models Data access abstracted from storage 3 © 2005 Progress Software Corporation Integration Layer Business Servicing Layer Data Access Layer Managed Data Stores Unmanaged Data Stores Implementing the OERA Implementing the OERA: What are the goals? Objectives Simplify your business 4 To provide an understanding of the OpenEdge Reference Architecture by describing a sample implementation To help you understand best practices for using OpenEdge features To motivate architects & lead developers to think about applying the OERA to their own projects © 2005 Progress Software Corporation Implementing the OERA Implementing the OERA: What are non-goals? Simplify your business Not a new framework Not intended to be comprehensive or to cover all application use cases Not intended to be commercialized Not intended to be used without changes, extensions, and understanding 5 © 2005 Progress Software Corporation Implementing the OERA How Should You Use It? Simplify your business 6 Use it to learn OERA concepts more deeply Use it to learn how best to use OpenEdge 4GL constructs and other features Consider it as a potentially useful starting point for OpenEdge 10 application development © 2005 Progress Software Corporation Implementing the OERA Who Is It For? Architects and Lead Developers with – A strong knowledge of Progress 4GL development – Familiarity with key OpenEdge 10 features – Access to the latest release – Plans Simplify your business 7 To re-implement an application, or application modules For a new development project © 2005 Progress Software Corporation Implementing the OERA What are the current OERI white papers? Simplify your business 1. Introduction 2. Business Entities and Data Access Objects 3. The Service Interface Layer 4. Using Advanced ProDataSet Language Features 5. Using an Unmanaged Data Store 6. Building a .NET Interface to Business Entities 8 © 2005 Progress Software Corporation Implementing the OERA What additional papers are planned? Simplify your business 7. Advanced Business Logic Issues 8. Context Management 9. Building a WebSpeed User Interface 10. Auditing 11… 9 © 2005 Progress Software Corporation Implementing the OERA What is in the sample implementation code base? Templates directory – Template procedures for BE’s, DAO’s etc. Support directory – Supporting supers & other procedures Samples directory Simplify your business – Code samples from the papers – These use sports2000 but there is nothing database-specific about any sample code 10 © 2005 Progress Software Corporation Implementing the OERA Where do I find it? The white papers and sample code are on the PSDN website at: – psdn.progress.com/library/product_info/ oera/index.ssp Simplify your business 11 There will be ongoing updates Second phase of 10.0 papers by Exchange Later material will describe best practices for using OE 10.1 and its OO4GL features © 2005 Progress Software Corporation Implementing the OERA Simplify your business 12 © 2005 Progress Software Corporation Implementing the OERA Agenda Simplify your business 13 Introducing the OERA Implementation Business Entities and Data Access Objects Business Logic Issues Introducing the Service Interface Layer Managing ProDataSet instances Context Management Conclusions © 2005 Progress Software Corporation Implementing the OERA The Business Entity and Data Access Object in the OERA Enterprise Services Users Presentation Layer Business Entity Simplify your business Data Access Object Business Servicing Layer Data Access Layer Managed Data Stores 14 © 2005 Progress Software Corporation Integration Layer Unmanaged Data Stores Implementing the OERA Business Entities and Data Access Objects The Business Entity manages the logical, internal view of application data The Data Access Object manages the physical data store Simplify your business – It also handles the mapping to the logic view of the data 15 © 2005 Progress Software Corporation Implementing the OERA Business Entities The Business Entity manages the logical, internal view of application data Simplify your business – Data for the user interface and other application layers – Business logic written against these logical definitions – Data best represented as ProDataSets and their temp-tables 16 The Business Entity is the core of the value of building applications in OpenEdge © 2005 Progress Software Corporation Implementing the OERA Data Access Objects The Data Access Object manages the physical data store Simplify your business – It understands the schema or other description of the physical data – It translates between this and the application’s logical view of the data – All references to the physical data store should be confined to the Data Access Object 17 © 2005 Progress Software Corporation Implementing the OERA Basic goals of these two object types Simplify your business 18 Keep the application logic unaware of and independent of the physical data storage Keep the Business Entities independent of the UI and other layers Define well-managed APIs to communicate between layers Build business objects according to welldefined templates and standards Provide for maximum flexibility and maintainability © 2005 Progress Software Corporation Implementing the OERA The ProDataSet as a building block ProDataSet Data-Source1 Query… Database Customer Lift Line Skiing Urpon Frisbee Hoops Croquet Q1 for Customer Field Map CustNum Name Contact CustomerTT 1 Lift Line Skiing 2 Urpon Frisbee 3 Hoops Croquet Order 1 2 3 53 81 66 Data-Relation1 01/01/93 01/04/93 01/04/93 Data-Source2 Query… Q2 for Order Field Map OrderNum CustNum OrderDate OrderTT 6 36 79 1 1 1 01/05/93 01/19/93 02/10/93 Event Logic Simplify your business Dataset:Before-fill Buffer:Before-fill Before-row-fill Row-Add Row-Delete … 19 © 2005 Progress Software Corporation Implementing the OERA Constructing the objects – temp-table definitions Define temp-tables for logical data definitions – Each temp-table in its own include file DEFINE TEMP-TABLE eOrder etOrder.i FIELD OrderNum… DEFINE TEMP-TABLE eOrderLine FIELD OrderNum… etOrderLine.i Simplify your business FIELD LineNum… 20 © 2005 Progress Software Corporation Implementing the OERA Temp-table Definitions These temp-tables are the internal view of the data Benefits: Simplify your business – Separate physical schema from logical – Separate server database connection from business logic – Allow a body of related data to be passed as a parameter (typically as part of a ProDataSet) – Allow a transaction scope independent of the database 21 © 2005 Progress Software Corporation Implementing the OERA Guidelines for temp-table definitions Use Temp-DB and Temp-DB Maintenance Tool Prefix table name with e – For example eCustomer Prefix include files with et – etCustomer.i Simplify your business Rename fields for consistency or comprehensibility Remove unwanted: – Fields – Indexes 22 © 2005 Progress Software Corporation Add other joined DB fields Add calculated fields that might be required for ease of use Add BEFORE-TABLE to end of definition when tracking changes Don’t use LIKE syntax – Temp-table LIKE databasetable – Field LIKE database-field Implementing the OERA Sample: etCustomer.i Simplify your business •TEMP-DB Maintenance Tool added in 10.0B Release can help maintain include files 23 © 2005 Progress Software Corporation Implementing the OERA One Temp-Table include file for each temp-table Code – samples\etOrder.i, etOrderLine, etItem /* Include file etOrder.i -- temp-table for Order DataSet */ Simplify your business DEFINE TEMP-TABLE eOrder BEFORE-TABLE eOrderBefore FIELD Ordernum AS INTEGER /* Include file etOrderline.i */ LABEL "Order Num" FORMAT "zzzzzzzzz9" INITIAL "0" FIELD CustNum AS INTEGER LABELBEFORE-TABLE "Cust Num" FORMAT ">>>>9" INITIAL "0" DEFINE TEMP-TABLE eOrderLine eOrderLineBefore FIELD OrderDate ASAS DATE LABELLABEL "Ordered" FORMAT "99/99/99""zzzzzzzzz9" INITIAL "TODAY" FIELD Ordernum INTEGER "Order Num" FORMAT INITIAL "0" FIELD ShipDate ASAS DATE LABELLABEL "Shipped" "99/99/9999" FIELD Linenum INTEGER "LineFORMAT Num" FORMAT ">>9" INITIAL "0" FIELD PromiseDate ASINTEGER DATE LABEL "Promised" FORMAT "99/99/99“ FIELD Itemnum AS LABEL "Item Num" FORMAT "zzzzzzzzz9" INITIAL "0" … … /* Include file etItem.i */ DEFINE TEMP-TABLE eItem BEFORE-TABLE eItemBefore FIELD Itemnum AS INTEGER LABEL "Item Num" FORMAT "zzzzzzzzz9" INITIAL "0" FIELD ItemName AS CHARACTER LABEL "Item Name" FORMAT "x(25)" … BEFORE-TABLE tracks changes! 24 © 2005 Progress Software Corporation Implementing the OERA Constructing the objects – Data-Source objects Build Data-Source object procedure – Each maps a temp-table to its physical data DEFINE DATA-SOURCE srcOrder etOrder.i FOR QUERY qOrder. sceOrder.p ATTACH-DATA-SOURCE() etOrderLine.i DEFINE DATA-SOURCE srcOrderLine sceOrderLine.p FOR BUFFER OrderLine. Simplify your business ATTACH-DATA-SOURCE() Application Database 25 © 2005 Progress Software Corporation Implementing the OERA Constructing the objects – ProDataSet definitions Define ProDataSets for sets of related data – Each is the basis for a Business Entity DEFINE DATASET dsOrder FOR eOrder, eOrderline… dsOrder.i etOrder.i Simplify your business etOrderLine.i 26 © 2005 Progress Software Corporation Implementing the OERA Building the ProDataSet include file Code sample: dsOrder.i – from template dsDataSet.i /* dsOrder.i -- ProDataSet definition for dsOrder. */ /* This is the signal that the include file reference is in an AppBuilder window. Define WINDOW-NAME therefore for all AppBuilder procedures, since the AppBuilder includes the temp-table includes on its own. */ &IF DEFINED(WINDOW-NAME) = 0 &THEN {etOrder.i} Temp-tables defined and included separately {etOrderLine.i} WINDOW-NAME preprocessor for the {etItem.i} AppBuilder &ENDIF Simplify your business DEFINE DATASET dsOrder FOR eOrder,eOrderLine,eItem DATA-RELATION OrderLine FOR eOrder,eOrderLine RELATION-FIELDS (OrderNum,OrderNum) DATA-RELATION LineItem FOR eOrderLine,eItem RELATION-FIELDS (ItemNum,ItemNum) REPOSITION. 27 © 2005 Progress Software Corporation Implementing the OERA Constructing the objects – Data Access Object Build Data Access Object for the DataSet – Manages all the Data-Source objects daOrder.p sceOrder.p dsOrder.i Simplify your business sceOrderLine.p 28 © 2005 Progress Software Corporation Implementing the OERA Building the Data Access Object Simplify your business Built from the template daEntity.p Naming convention of da + entity-name Includes the ProDataSet definition file Can also include FILL logic that is beyond a single temp-table 29 © 2005 Progress Software Corporation Implementing the OERA All the Data Access components together daOrder.p {dsOrder.i} {daEntity.i} SUPER daSupport.p initDataSources: sceOrder.p DEF DATA-SOURCE ATTACH-DATA-SOURCE RowFill handler sceOrderLine.p DEF DATA-SOURCE ATTACH-DATA-SOURCE SUPER Simplify your business sceItem.p DEF DATA-SOURCE ATTACH-DATA-SOURCE SUPER 30 Application Database daOrderValidate.p (optional) eOrderLineModifyBeginTrans: © 2005 Progress Software Corporation Implementing the OERA The Data Access Object as a compound object Simplify your business 31 Everything is a super procedure of the DAO The related procedures are started according to naming conventions Can be run just once in a session and left running Its parts can be reassembled in different ways Validation logic can be in the DAO or delegated to a separate procedure © 2005 Progress Software Corporation Implementing the OERA Constructing the objects – Business Entities Build a Business Entity for each ProDataSet – Manages business logic on the logical data – Defines the API for access from other objects dsOrder.i DEFINE DATASET dsOrder FOR eOrder, eOrderline… etOrder.i Simplify your business etOrderLine.i BusinessLogic: END PROCEDURE. 32 © 2005 Progress Software Corporation Implementing the OERA Building the Business Entity Simplify your business Based on a template: beEntity.p Naming convention: be + entity name Standard behavior starts the DAO Supporting super procedure Optional separate validation procedure 33 © 2005 Progress Software Corporation Implementing the OERA Business Entity components together dsOrder.i beOrder.p {etOrder.i} {etOrderLine.i} {etItem.i} {dsOrder.i} {beEntity.i} beEntity.i beSupport.p fetchCustom saveChanges DEFINE DATASET… RUN daOrder.p Simplify your business SUPER SUPER beOrderValidate.p (optional) eOrderLineModifyPreTrans: Data Access Object 34 © 2005 Progress Software Corporation Implementing the OERA Agenda Simplify your business 35 Introducing the OERA Implementation Business Entities and Data Access Objects Business Logic Issues Introducing the Service Interface Layer Managing ProDataSet instances Context Management Conclusions © 2005 Progress Software Corporation Implementing the OERA Example of “magic” behavior: Callbacks set by daSupport.p Code – support\daSupport.p PROCEDURE initDataSources : /* …code snippet that shows dataset check there is also code to generically check all buffers for callbacks - Look for DataSet-level events first. */ Simplify your business IF LOOKUP(phDataSet:NAME + "BeforeFill", cEntries) NE 0 THEN phDataSet:SET-CALLBACK-PROCEDURE ("BEFORE-FILL", phDataSet:NAME + "BeforeFill", TARGET-PROCEDURE). IF LOOKUP(phDataSet:NAME + "AfterFill", cEntries) NE 0 THEN phDataSet:SET-CALLBACK-PROCEDURE ("AFTER-FILL", phDataSet:NAME + "AfterFill", TARGET-PROCEDURE). /* …*/ 36 © 2005 Progress Software Corporation Implementing the OERA Data Access Object logic Issues Leave out logic that doesn’t need access to the physical data – That belongs in the Business Entity Decide where the logic should go – – – – Simplify your business Single-table logic in its Data-Source proc Logic with a larger scope in the DAO Static versus dynamic table references Access to other DAOs through their APIs for complex requests – Interaction with database trigger procs 37 © 2005 Progress Software Corporation Implementing the OERA Data Access Object FILL logic Example of logic that references more than one table in the ProDataSet – This should go into the Data Access Object itself PROCEDURE eOrderLineAfterFill: DEFINE INPUT PARAMETER DATASET FOR dsOrder. DEFINE VARIABLE dTotal AS DECIMAL NO-UNDO. Simplify your business FOR EACH OrderLine WHERE OrderLine.OrderNum = eOrder.OrderNum: dTotal = dTotal + OrderLine.ExtendedPrice. END. eOrder.OrderTotal = dTotal. END PROCEDURE. 38 © 2005 Progress Software Corporation Implementing the OERA Data-Source Object FILL logic Example of dynamic table reference: – Dynamic reference allows reuse PROCEDURE eItemAfterRowFill: DEFINE INPUT PARAMETER DATASET-HANDLE phDataSet. …. hItemName = phDataSet:GET-BUFFER-HANDLE("eItem"):BUFFER-FIELD("ItemName"). Simplify your business DO iType = 1 TO NUM-ENTRIES(cItemTypes): cType = ENTRY(iType, cItemTypes). IF INDEX(hItemName:STRING-VALUE, cType) NE 0 THEN hItemName:BUFFER-VALUE = REPLACE(hItemName:BUFFER-VALUE, cType, cType). END. END PROCEDURE. 39 © 2005 Progress Software Corporation Implementing the OERA Business Entity logic Simplify your business 40 Validation and other business logic Logic references the internal logical view of the data References to other entities through their published APIs Logic requiring knowledge of the physical schema is deferred to DAOs © 2005 Progress Software Corporation Implementing the OERA Business Entity logic issues How strictly do I adhere to logic separation? – Do I use an API call just for a CAN-FIND? – Do I defer that to a database trigger? Simplify your business How do I adjust BE logic to allow for re-use of tables in other ProDataSets? When do I use static versus dynamic table and ProDataSet references? 41 © 2005 Progress Software Corporation Implementing the OERA Business Entity update semantics in the sample implementation Generic saveChanges for one or multiple rows in any number of related tables Callouts to validation hooks based on procedure names Database transaction per row Can be modified to provide: Simplify your business – Custom control logic for the whole update – Saving all changes as a single transaction – Extensions to error handling logic 42 © 2005 Progress Software Corporation Implementing the OERA Agenda Simplify your business 43 Introducing the OERA Implementation Business Entities and Data Access Objects Business Logic Issues Introducing the Service Interface Layer Managing ProDataSet instances Context Management Conclusions © 2005 Progress Software Corporation Implementing the OERA SOA – Service Interaction Model Broker/ Director y Service Find / Details Service Requestor Publish Bind Invoke Service Provide r Enterprise Services Simplify your business Bus Task Bus Task Bus Task 44 © 2005 Progress Software Corporation Implementing the OERA Application Domain Services Presentation Container Domain Fn() Service Proxy Service Container Simplify your business Service Interface Order Mgmt 45 © 2005 Progress Software Corporation Financials Other Services Implementing the OERA Container Managed – Support Services Presentation Container Client Side Service Proxy Simplify your business Service Interface Auditing Security Service Container Order Mgmt Server Side 46 © 2005 Progress Software Corporation Session/Context Management Fn() … Implementing the OERA The Service Interface Layer in the OERA Enterprise Services Users Presentation Layer Service Interface Integration Layer Business Servicing Layer Simplify your business Data Access Layer Managed Data Stores 47 © 2005 Progress Software Corporation Unmanaged Data Stores Implementing the OERA Role of the sample Service Interface Layer Manages server-side entities – Keeps an in-memory catalog of running instances Simplify your business Provides standard one-call access to server-side procedures Provides a single simplified API from client to server 48 © 2005 Progress Software Corporation Implementing the OERA The Service Interface Layer Client Server UI Procedure Business Entity Data-Access Object DATASET dsOrder DATASET dsOrder RUN fetchOrder RUN FetchWhere fetchWhere: IN hEntity FILL (. . ., ATTACH (. . . , OUTPUT DATASET dsOrder Simplify your business BY-REFERENCE) 49 Client Proxy Procedure IN hdsOrder © 2005 Progress Software Corporation Server Gateway Procedure DATASET dsOrder OUTPUT DATASET phFetchDataSet BY-REFERENCE) Implementing the OERA Client-side SI proxy User interface Client proxy procedure procedure dsOrderWinAdv.w Simplify your business {dsOrder.i} {proSIproxyStart.i} … RUN fetchWhere IN ghProxySIproc (INPUT “Order”, INPUT ttContextDSOrder, OUTPUT DataSet dsOrder). proSIproxy.p PROC fetchWhere: RUN proSIgateway.p ON hAppServer (INPUT “Order”, INPUT “fetchWhere”…) PROC saveChanges: … (call to server-side gateway) 50 © 2005 Progress Software Corporation Implementing the OERA Server-side SI procedures Server service (call from client session) Server gateway procedure proSIgateway.p hEntity = getEntityHandle in hSI. RUN fetchWhere in hEntity procedure proSIserver.p DEFINE T-T ttEntity… FN startEntity: FN getEntityHandle: FN getDAOHandle: Simplify your business … (call to Business Entity API) 51 © 2005 Progress Software Corporation Implementing the OERA Gateway procedure API Five standard parameters – Logical entity name – Logical operation name – Context/parameter temp-table for passing any related values back and forth – OUTPUT or INPUT-OUTPUT ProDataSet – OUTPUT status for exception handling Useful default for many operations Simplify your business 52 © 2005 Progress Software Corporation Implementing the OERA Agenda Simplify your business 53 Introducing the OERA Implementation Business Entities and Data Access Objects Business Logic Issues Introducing the Service Interface Layer Managing ProDataSet instances Context Management Conclusions © 2005 Progress Software Corporation Implementing the OERA Management of ProDataSet instances Simplify your business Which object “owns” the ProDataSet instance on server and client? ProDataSets can be passed BY-REFERENCE to avoid copying The caller’s instance is always used, even on OUTPUT 54 © 2005 Progress Software Corporation Implementing the OERA ProDataSet instances on OUTPUT Client Server UI Procedure Business Entity Data-Access Object DATASETDATASET dsOrder BY-REF HANDLE HANDLE (. . . , OUTPUT DATASET dsOrder Simplify your business BY-REFERENCE) 55 Client Proxy Procedure IN hdsOrder © 2005 Progress Software Corporation Server Gateway Procedure RUN fetchOrder DATASET dsOrder BY-REF DATASET dsOrder RUN FetchWhere fetchWhere: IN hEntity FILL (. . ., ATTACH OUTPUT DATASET phFetchDataSet BY-REFERENCE) Implementing the OERA ProDataSet instance on INPUT-OUTPUT Client Server UI Procedure DATASET dsOrder Business Entity DATASETHANDLE HANDLE BY-REF (. . . , OUTPUT DATASET dsOrder Simplify your business BY-REFERENCE) 56 Client Proxy Procedure IN hdsOrder © 2005 Progress Software Corporation Server Gateway Procedure RUN fetchOrder DATASET dsOrder Data-Access Object BY-REF DATASET dsOrder RUN FetchWhere fetchWhere: IN hEntity FILL (. . ., ATTACH OUTPUT DATASET phFetchDataSet BY-REFERENCE) Implementing the OERA Agenda Simplify your business 57 Introducing the OERA Implementation Business Entities and Data Access Objects Business Logic Issues Introducing the Service Interface Layer Managing ProDataSet instances Context Management Conclusions © 2005 Progress Software Corporation Implementing the OERA Context Management basics Simplify your business Target environment is client to stateless AppServer Each interaction is independent Maintain context between related interactions 58 © 2005 Progress Software Corporation Implementing the OERA Passing context between client and server Context/Parameter temp-table passes context back and forth Name & Value fields allow flexibility Context is maintained on the client Useful for small amounts of data Simplify your business – Also for context used on the client – And for context modified on the client 59 © 2005 Progress Software Corporation Implementing the OERA Context between client and server Server Client Business Entity UI Procedure DATASET dsOrder DATASET dsOrder (. . . , OUTPUT DATASET dsOrder Simplify your business BY-REFERENCE) 60 Client Proxy Procedure IN hdsOrder temp-table WhereString = “…” NextRowid = 63524 © 2005 Progress Software Corporation RUN FetchWhere Server Gateway Procedure context/parameter RUN fetchOrder IN hEntity (. . ., OUTPUT DATASET phFetchDataSet BY-REFERENCE) Implementing the OERA Client to Server context example – support for data batching Simplify your business WhereString = “OrderNum = 27” NextRowid = 63726 Server reprepares and reopens the database query on each call NEXT-ROWID ProDataSet attribute tells server where to restart retrieval 61 © 2005 Progress Software Corporation Implementing the OERA Context maintained on the server Hold context in a shared server-side data store Useful for context not to pass back and forth – Session context such as language, authorization Requires a Context ID passed from the client Simplify your business – GUID support in sample and in OE 10.1 62 © 2005 Progress Software Corporation Implementing the OERA Context stored on the server Server Client Business Entity UI Procedure DATASET dsOrder DATASET dsOrder (. . . , OUTPUT DATASET dsOrder Simplify your business BY-REFERENCE) Client Proxy Procedure IN hdsOrder temp-table ContextID = 95847 RUN FetchWhere Server Gateway Procedure context/parameter RUN fetchOrder IN hEntity (. . ., OUTPUT DATASET phFetchDataSet BY-REFERENCE) 95847 English Auth … 63 © 2005 Progress Software Corporation Implementing the OERA ProDataSet and temp-table context Store retrieved data in a context table – For WebSpeed or other clients with no ProDataSet support – RAW fields and BLOBS for generic storage Store successive updates before commit Simplify your business – Allows partial validation on the server – Final update ProDataSet rebuilt from context 64 © 2005 Progress Software Corporation Implementing the OERA ProDataSet / temp-table data as context Server Client Business Entity UI Procedure DATASET dsOrder DATASET dsOrder ContextID = 95847 (. . . , OUTPUT DATASET dsOrder Simplify your business BY-REFERENCE) Client Proxy Procedure IN hdsOrder “OrderNum = 1” 95847 Order 1 Line 1 RUN FetchWhere Server Gateway Procedure RUN fetchOrder IN hEntity (. . ., OUTPUT DATASET phFetchDataSet BY-REFERENCE) 95847 Order 1 Line 1 95847 Order 1 Line 2 65 © 2005 Progress Software Corporation Implementing the OERA Agenda Simplify your business 66 Introducing the OERA Implementation Business Entities and Data Access Objects Business Logic Issues Introducing the Service Interface Layer Managing ProDataSet instances Context Management Conclusions © 2005 Progress Software Corporation Implementing the OERA Directions Simplify your business First set of papers & examples on PSDN New papers coming before Exchange Significant new language extensions planned for 10.1 and beyond Materials to be revised and extended to describe 10.1 best practices 67 © 2005 Progress Software Corporation Implementing the OERA In Summary Simplify your business 68 View the sample OERA materials as a basis for discussion and learning Use parts that are useful Extend or replace for your own purposes Expect it continue to grow and change Don’t expect it to be completed or formally supported © 2005 Progress Software Corporation Implementing the OERA Simplify your business Questions? 69 © 2005 Progress Software Corporation Implementing the OERA Simplify your business Thank you for your time! 70 © 2005 Progress Software Corporation Implementing the OERA Simplify your business 71 © 2005 Progress Software Corporation Implementing the OERA