840 likes | 952 Views
E133 Moving PB Apps to a distributed platform. Bill Green VP Emerging Technologies Power 3 wgreen@power3.com. Marketing. Customized Training PowerBuilder, Internet, Software Quality Assurance Hands-On Classroom training On-Site Mentoring Component Development Practice
E N D
E133Moving PB Apps to a distributed platform Bill Green VP Emerging Technologies Power3 wgreen@power3.com
Marketing • Customized Training • PowerBuilder, Internet, Software Quality Assurance • Hands-On Classroom training • On-Site Mentoring • Component Development Practice • Software Quality Practice
Objective for today • Talk about what Sybase offers today in terms of distributed computing development • Walkthrough a typical PFC-based PowerBuilder application transition from 2-tier client-server to n-tier client-server
Multi-tier, Internet/Intranet Multi-tier, Windows Client Thin Client, Thick Server GUI Browser Thick Client User Services User Services GUI GUI Interface Logic Interface Logic Web Server Business Logic Business Services Data Services Business Logic Data Services Data Services Data Access Logic Data Access Logic CICS DBMS DBMS DBMS Data Messages Technology Architecture Servers Client Development Scenarios today
Multi-tier, Internet/Intranet Multi-tier, Windows Client GUI Browser User Services User Services Web Server Business Services Data Services Data Services Data Services CICS DBMS What’s needed today? • We still need good 2-tier client-server tools • We need good HTML and Java development tools • We need a good web-server so that browser based applications can be conversational • Most of all we need a good application server
Multi-tier, Internet/Intranet Multi-tier, Rich Client Browser GUI User Services User Services Page Server Business Services Data Services Enterprise Application Server Data Services Data Services CICS DBMS Developing with PowerJ Applets Java Applications JavaScript JSP, Servlets, EJB Java in the Database Exec Java Classes Col Java Classes
Multi-tier, Internet/Intranet Multi-tier, Rich Client Browser GUI User Services User Services PowerBuilder PowerBuilder PowerBuilder PowerBuilder Page Server Business Services Data Services Enterprise Application Server Data Services Data Services CICS DBMS Developing with PowerBuilder HTML Pages PB Applications DynaScript PowerBuilder NVO’s
Distributed Computing Development • It’s an arduous task to scan through an application looking for business logic • Try to use whatever automated tools possible to perform this analysis • There are three approaches possible When you’re faced with a non-partitioned application with the task of partitioning it, the most common reaction is “Who wrote this stuff?”
Approaches • You can reverse engineer the application • You can scan for business logic and extract it to business objects • Wait for business need to target an area of functionality
Ideal Approach • You can reverse engineer the application • You can scan for business logic and extract it to business objects • Wait for business need to target an area of functionality
Unfortunately • Real World: “We need this done in 6 weeks” • The real world dictates what approach will be taken rather than a sense of what will work best
Demo Reverse Engineering • No tools available to do this automatically, but... • Rational Rose/PB will reverse engineer • HOW will reverse engineer • PowerDesigner will reverse engineer • These tools can only define classes based on your existing objects - Often not very useful as your design will change • Useful as documentation of your existing application • If application is well-partitioned already, these tools can reduce the amount of time needed
Application Scanning • Time consuming • Prone to error • Very few tools available to assist • Most probable route chosen in the real world - Do everything at once, and do it now!
Wait for the business need • Targeted application scanning • Working only with the code affected by the business need • Follows the same steps as scanning • Best Approach for existing PB apps - Almost never the route chosen
Directive from Marketing: Get our Sales application to the web! Now!!
The existing system • A simple Sales Order system • Based on the PFC • Sales Order Entry w_sales_order • Customer Maintenance w_Customer
Live Action Demo The Sales Order System Place an Order Evaluate Sales Order Calculate Discount Complete the Sale Create the Order
Analyze the existing system • Scan the existing code • Remember, you’re looking for Business Logic that should be partitioned • Review: • Where do you look?
What to look for • Logic imbedded in datawindow objects • Evaluation Rules • Grouping rules • Calculations • Expressions • Logic imbedded in datawindow controls • Click, ItemChanged, EditChanged most prevalent • Save cycle logic most important, location undetermined • Logic imbedded in Windows and other objects • Save Cycles most obvious point to look
Code Review Review Findings w_sales_order dw_salesorder ::pfc_preupdate Discount Logic ::pfc_preinsertrow New Cust ID SOS-1 In DataWindow Code dw_sales_order_items ::itemchanged Get Price In DataWindow Object Expressions d_sales_order_items (DataObject) ::Default Ship Date = Today Also look in Window events, called service objects etc Behind Buttons Discount Logic
Analyze the existing system • Discount Code Calculation is implemented in different areas and in different ways • preupdate event • Coded behind a button • potentially, elsewhere • Some business rules are implemented incorrectly • Default Ship-date = Today() • Should be based on location • We also note that several business rules aren’t implemented at all • Order not checked for Order Items • Diagnosis: Unhealthy!
What to do when you find logic • Document the logic as close to a method or rule as possible • Group and sub-group the methods and rules into logical groups • Discount Code Calculation Sales Orders • Ship-Date Calculation Sales Order Items • Product Price Product • Compare with the original function specs for the system and discuss with users • Design and code new business objects
Design the business objects • Itemize the Use Cases that will apply • If you are not familiar with Use Cases, think in terms of a business process • Itemize the rules that will apply • Determine which rules will apply locally • What is affected by user entered data and is not dependent on other data • Categorize the rules and Use Cases into groups • These groups will become your Business Objects • Build Class Definitions for your business objects
Design Techniques for components • Remember you’re designing ultimately to be distributable so keep in mind: • Create your NEW NVO’s as Jaguar Components • If you already have Business Logic coded in NVO’s, check: • Add an Activate event (pbm_ComponentActivate) - Copy any constructor code here • Same for Deactivate and copy Destructor code • Replace any references to “DataStore” with a userobject version of a datastore
Review: Partitioned Logic w_sales_order All Sales Order logic goes in the Sales Order Object n_bo_salesorder of_calculatediscount() of_get_nextOrderID() All of this currently runs on the client...
Review: Partitioned Logic w_sales_order n_bo_salesorder of_calc_discount() of_get_nextOrderID() Sales Order Item logic goes in the Sales Order Items object n_bo_salesorderitems of_calc_shipdate() All of this currently runs on the client...
Review: Partitioned Logic w_sales_order n_bo_salesorder of_calc_discount() of_get_nextOrderID() n_bo_salesorderitems of_calc_shipdate() Functions relating to Product go in the Product object n_bo_product of_get_productprice() All of this currently runs on the client...
Review: Partitioned Logic - Local Rules w_sales_order n_bo_salesorder of_calc_discount() of_get_nextOrderID() n_bo_salesorderitems of_calc_shipdate() • Local validation rules • n_bo_lr_salesorders • Order Date = Today • n_bo_lr_salesorderitems • Unit Price > $5.00 n_bo_product of_get_productprice() All of this currently runs on the client...
What are Local Rules? • Local rules are those rules which apply to your data at the point of entry • Examples: • Column Initialization (Local Only) • Setup the initial value for a column (Initial Value) • Column Validation (Local Only) • Entered value is valid (Validation Rule) • Notification (Local Only) • Highlight cells for notification • Data Validation (Local & Remote) • Data entered meets specified business requirements
Column Initial Value setup • dw_sales_order • PostInsert event • OrderDate set to today
Column/Data Validation rule • Sales Order Items • Unit Price rule • Unit price may not be less than $5.00
When to Use Local Rules • When rules need to be applied at point of entry • When data required is contained within the cell or row being edited • Local Rules should not require processing beyond the scope of the local object
Live Action Demo How do you create Local Rules • Local Rules objects is an NVO just like any other service object • example: n_bo_lr_salesorderitems • Implemented as a service in either the client or server object • Rules are built through a function that is defined to do 2 things • Generate a Modify() statement to implement the rule in a datawindow/datastore • Create an Evaluation statement that can be executed by passing parameters
Now we determine separation • Decide what will run on the server and what will run on the client • Anything that runs on the client is what would be needed to replicate the functionality in a different front-end (eg: Internet) • Remember that Local Rules should also be implemented on the Server for clients that do not have PB’s client-side validation capabilities(HTML)
Partitioning Logic - Location w_sales_order This should go on the server n_bo_salesorder of_calculatediscount() of_get_nextOrderID() n_bo_salesorderitems of_calc_shipdate() • Local validation rules • n_bo_lr_salesorders • Order Date = Today • n_bo_lr_salesorderitems • Unit Price > $5.00 n_bo_product of_getproductprice() PBL: Sales_order_NVOs All of this currently runs on the client...
Partitioning Logic - Location w_sales_order n_bo_salesorder of_calculatediscount() of_get_nextOrderID() This should go on the server n_bo_salesorderitems of_calc_shipdate() • Local validation rules • n_bo_lr_salesorders • Order Date = Today • n_bo_lr_salesorderitems • Unit Price > $5.00 n_bo_product of_getproductprice() PBL: Sales_order_NVOs All of this currently runs on the client...
Partitioning Logic - Location w_sales_order n_bo_salesorder of_calculatediscount() of_get_nextOrderID() n_bo_salesorderitems of_calc_shipdate() This should go on the server • Local validation rules • n_bo_lr_salesorders • Order Date = Today • n_bo_lr_salesorderitems • Unit Price > $5.00 n_bo_product of_getproductprice() PBL: Sales_order_NVOs All of this currently runs on the client...
Partitioning Logic - Location w_sales_order n_bo_salesorder of_calculatediscount() of_get_nextOrderID() n_bo_salesorderitems of_calc_shipdate() • Local validation rules • n_bo_lr_salesorders • Order Date = Today • n_bo_lr_salesorderitems • Unit Price > $5.00 n_bo_product of_getproductprice() Where should Local Rules go? All of this currently runs on the client...
Partitioning Logic - Location w_sales_order n_bo_salesorder of_calculatediscount() of_get_nextOrderID() • Local validation rules • n_bo_lr_salesorders • Order Date = Today • n_bo_lr_salesorderitems • Order Item Quantity > 0 n_bo_salesorderitems of_calc_shipdate() • Local validation rules • n_bo_lr_salesorders • Order Date = Today • n_bo_lr_salesorderitems • Order Item Quantity > 0 n_bo_product of_getproductprice() On both sides Even better if stored on the server and downloaded to the client All of this currently runs on the client...
Partitioning Logic - Location w_sales_order n_bo_salesorder of_calculatediscount() of_get_nextOrderID() • Local validation rules • n_bo_lr_salesorders • Order Date = Today • n_bo_lr_salesorderitems • Order Item Quantity > 0 n_bo_salesorderitems of_calc_shipdate() • Local validation rules • n_bo_lr_salesorders • Order Date = Today • n_bo_lr_salesorderitems • Order Item Quantity > 0 n_bo_product of_getproductprice() This should NOT go on the server. Why? All of this currently runs on the client...
We separate the items accordingly w_sales_order n_bo_salesorder of_calculatediscount() of_get_nextOrderID() • Local validation rules • n_bo_lr_salesorders • Order Date = Today • n_bo_lr_salesorderitems • Order Item Quantity > 0 n_bo_salesorderitems of_calc_shipdate() • Local validation rules • n_bo_lr_salesorders • Order Date = Today • n_bo_lr_salesorderitems • Unit Price > $5.00 n_bo_product of_getproductprice() This runs on the server This runs on the client
Data Access Components • Get data from DB • Pass data to client • Monitor data changes • Apply business rules • Apply updates
Code Review Distributed Data Access • We’d like to insulate our data access for customer • Create a Customer Business Object • Provide Methods for retrieving customer(s) • Provide Method for sending updates • Note:This object is being designed with state.It keeps customer information in memory while the client performs work
Data Access and Synchronization • GetFullState( blob, {cookie} ) • Grabs all info from one dw to be replicated elsewhere. • SetFullState( blob ) • Puts info from a dw into another • GetStateStatus( cookie ) • Used to create a changes cookie • GetChanges( blob ) • use the GetStateStatus cookie to determine if changes are likely to succeed • Generates a ‘changeblob’ for use in SetChanges • SetChanges • Applies changes
Passing Data w_customer n_bo_customer of_GetCustomer() This runs on the client This runs on the server
Passing Data w_customer n_bo_customer 1 ABC Co. IL 2 XYZ Inc. GA 3 Jones Inc. NC of_GetCustomer() Retrieve() This runs on the client This runs on the server
Passing Data (GetFullState) w_customer n_bo_customer 1 ABC Co. IL 2 XYZ Inc. GA 3 Jones Inc. NC of_GetCustomer() Retrieve() GetFullState() This runs on the client This runs on the server
3 Rows Passing Data (SetFullState) w_customer n_bo_customer 1 ABC Co. IL 2 XYZ Inc. GA 3 Jones Inc. NC of_GetCustomer() Retrieve() GetFullState() 1 ABC Co. IL 2 XYZ Inc. GA 3 Jones Inc. NC SetFullState() This runs on the client This runs on the server
3 Rows Passing Data (Data Changes) w_customer n_bo_customer 1 ABC Co. IL 2 XYZ Inc. GA 3 Jones Inc. NC of_GetCustomer() Retrieve() GetFullState() 1 ABC Co. IL 2 XYZ Inc. GA 3 Jones Inc. NC 1 ABC Co. IL 2 XYZ Inc. NJ 3 Jones Inc. NC SetFullState() This runs on the client This runs on the server