Title: E133 Moving PB Apps to a distributed platform
1E133Moving PB Apps to a distributed platform
- Bill Green
- VP Emerging Technologies
- Power3
- wgreen_at_power3.com
2Marketing
- Customized Training
- PowerBuilder, Internet, Software Quality
Assurance - Hands-On Classroom training
- On-Site Mentoring
- Component Development Practice
- Software Quality Practice
3Objective 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
4Development Scenarios today
5Whats 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
6Developing with PowerJ
Applets
Java Applications
JavaScript
JSP, Servlets, EJB
Java in the Database Exec Java Classes Col Java
Classes
7Developing with PowerBuilder
HTML Pages
PB Applications
DynaScript
PowerBuilder NVOs
8Distributed Computing Development
- Its 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 youre
faced with a non-partitioned application with the
task of partitioning it, the most common reaction
is -
Who wrote this stuff?
9Approaches
- 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
10Ideal 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
11Unfortunately
- 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
12Reverse 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
13Application 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!
14Wait 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
15Directive from Marketing
- Get our Sales application to the web! Now!!
16The existing system
- A simple Sales Order system
- Based on the PFC
- Sales Order Entry w_sales_order
- Customer Maintenance w_Customer
17The Sales Order System
Place an Order
Evaluate Sales Order
Calculate Discount
Complete the Sale
Create the Order
18Analyze the existing system
- Scan the existing code
- Remember, youre looking for Business Logic that
should be partitioned - Review
- Where do you look?
19What 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
20Review 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
21Analyze 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 arent
implemented at all - Order not checked for Order Items
- Diagnosis Unhealthy!
22What 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
23Design 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
24Design Techniques for components
- Remember youre designing ultimately to be
distributable so keep in mind - Create your NEW NVOs as Jaguar Components
- If you already have Business Logic coded in
NVOs, 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
25Review Partitioned Logic
w_sales_order
All Sales Order logic goes in the Sales Order
Object
n_bo_salesorder of_calculatediscount() of_get_next
OrderID()
All of this currently runs on the client...
26Review Partitioned Logic
w_sales_order
n_bo_salesorder of_calc_discount() of_get_nextOrde
rID()
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...
27Review Partitioned Logic
w_sales_order
n_bo_salesorder of_calc_discount() of_get_nextOrde
rID()
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...
28Review Partitioned Logic - Local Rules
w_sales_order
n_bo_salesorder of_calc_discount() of_get_nextOrde
rID()
n_bo_salesorderitems of_calc_shipdate()
Local validation rules n_bo_lr_salesorders Order
Date Today n_bo_lr_salesorderitems Unit Price gt
5.00
n_bo_product of_get_productprice()
All of this currently runs on the client...
29What 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
30Column Initial Value setup
- dw_sales_order
- PostInsert event
- OrderDate set to today
31Column/Data Validation rule
- Sales Order Items
- Unit Price rule
- Unit price may not be less than 5.00
32When 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
33How 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
34Now 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 PBs client-side validation
capabilities(HTML)
35Partitioning Logic - Location
w_sales_order
This should go on the server
n_bo_salesorder of_calculatediscount() of_get_next
OrderID()
n_bo_salesorderitems of_calc_shipdate()
Local validation rules n_bo_lr_salesorders Order
Date Today n_bo_lr_salesorderitems Unit Price gt
5.00
n_bo_product of_getproductprice()
PBL Sales_order_NVOs
All of this currently runs on the client...
36Partitioning Logic - Location
w_sales_order
n_bo_salesorder of_calculatediscount() of_get_next
OrderID()
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 gt
5.00
n_bo_product of_getproductprice()
PBL Sales_order_NVOs
All of this currently runs on the client...
37Partitioning Logic - Location
w_sales_order
n_bo_salesorder of_calculatediscount() of_get_next
OrderID()
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 gt
5.00
n_bo_product of_getproductprice()
PBL Sales_order_NVOs
All of this currently runs on the client...
38Partitioning Logic - Location
w_sales_order
n_bo_salesorder of_calculatediscount() of_get_next
OrderID()
n_bo_salesorderitems of_calc_shipdate()
Local validation rules n_bo_lr_salesorders Order
Date Today n_bo_lr_salesorderitems Unit Price gt
5.00
n_bo_product of_getproductprice()
Where should Local Rules go?
All of this currently runs on the client...
39Partitioning Logic - Location
w_sales_order
n_bo_salesorder of_calculatediscount() of_get_next
OrderID()
Local validation rules n_bo_lr_salesorders Order
Date Today n_bo_lr_salesorderitems Order Item
Quantity gt 0
n_bo_salesorderitems of_calc_shipdate()
n_bo_product of_getproductprice()
Local validation rules n_bo_lr_salesorders Order
Date Today n_bo_lr_salesorderitems Order Item
Quantity gt 0
On both sides Even better if stored on the server
and downloaded to the client
All of this currently runs on the client...
40Partitioning Logic - Location
w_sales_order
n_bo_salesorder of_calculatediscount() of_get_next
OrderID()
Local validation rules n_bo_lr_salesorders Order
Date Today n_bo_lr_salesorderitems Order Item
Quantity gt 0
n_bo_salesorderitems of_calc_shipdate()
n_bo_product of_getproductprice()
Local validation rules n_bo_lr_salesorders Order
Date Today n_bo_lr_salesorderitems Order Item
Quantity gt 0
This should NOT go on the server. Why?
All of this currently runs on the client...
41We separate the items accordingly
w_sales_order
n_bo_salesorder of_calculatediscount() of_get_next
OrderID()
Local validation rules n_bo_lr_salesorders Order
Date Today n_bo_lr_salesorderitems Order Item
Quantity gt 0
n_bo_salesorderitems of_calc_shipdate()
Local validation rules n_bo_lr_salesorders Order
Date Today n_bo_lr_salesorderitems Unit Price gt
5.00
n_bo_product of_getproductprice()
This runs on the client
This runs on the server
42What else would we separate?
43Data Access Components
- Get data from DB
- Pass data to client
- Monitor data changes
- Apply business rules
- Apply updates
44Distributed Data Access
- Wed like to insulate our data access for
customer - Create a Customer Business Object
- Provide Methods for retrieving customer(s)
- Provide Method for sending updates
- NoteThis object is being designed with
state.It keeps customer information in memory
while the client performs work
45Data 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
46Passing Data
w_customer
n_bo_customer
of_GetCustomer()
This runs on the client
This runs on the server
47Passing 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
48Passing 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
49Passing 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
50Passing 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
51Passing Data (GetChanges)
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()
GetChanges()
This runs on the client
This runs on the server
52Passing Data (SetChanges)
w_customer
n_bo_customer
1 ABC Co. IL 2 XYZ Inc. GA 3 Jones Inc. NC
1 ABC Co. IL 2 XYZ Inc. NJ 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()
of_UpdateCustomer()
SetChanges()
GetChanges()
This runs on the client
This runs on the server
53Passing Data (SetChanges)
w_customer
n_bo_customer
1 ABC Co. IL 2 XYZ Inc. GA 3 Jones Inc. NC
1 ABC Co. IL 2 XYZ Inc. NJ 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()
of_UpdateCustomer()
SetChanges() Update()
GetChanges()
Update Result returned to client
This runs on the client
This runs on the server
54OK, so we have components. Now what?
- Deploy the component to Jaguar
- Change the Client Application to access the
Jaguar Component instead of the local components
55Deploy the component to Jaguar
- Create a Jaguar Component Project using the
Project Component Wizard
56Prepare the client - stage 1
- Create Proxies of the Jaguar Components
- Use the Jaguar Proxy Wizard
- Target the application library for the proxies
- Remove the actual component library from the
search path
57Prepare the client - Stage 2
- Connect the application to the Jaguar Server
- Use the wizard to create a customized connection
object
58Prepare the client - Stage 3
- Connect to the Jag Server
- Create the component using CreateInstance()
59Prepare the client - Stage 4
60Accessing from a client application
PB native NVOs residing in Jaguar
n_bo_customer of_GetCustomer() of_GetCustomers() o
f_UpdateCustomer()
PB Client
Connection ConnectToServer()
n_bo_salesorders of_getnextorderid() of_calcdiscou
nt() of_insertsalesorder()
Proxy CreateInstance() n_bo_customer of_GetCustome
r() of_GetCustomers() of_UpdateCustomer()
61Accessing from the Web
- Natively via HTML
- Using PowerDynamo
- Using JSPs
62Hardware Structure
Typical
63Needs Issues
- Servlet Class Library from www.servlets.com
contains File Upload class - Create a Servlet that will accept the HTML
request, call the File Upload and then connect
to, and call EAServer
- We need something that can accept Files from a
browser - We need a class that can call an EAServer
Component
64Direct Web Access
- What if we wanted to access our PowerBuilder
component directly from an HTML page? - Normally, you cant. But if you use a servlet as
the intermediary. - Introducing JAWS
65Jaguar Agent for Web Servers
- JAWS can be downloaded from the Sybase Website.
It is a Servlet that provides HTTP access to your
PowerBuilder components
66Java Server Pages (JSP)
- Java Server Pages are sort of a mutated
combination of HTML and Servlets. A JSP page is
an HTML page with some special tags that allow
you to use data much the same way you would in a
servlet. You can also call Java code directly. - A JSP is compiled into a Servlet and is run on
the server. - So, a JSP Page is a server-side HTML page that
can speak Java.
67Java Server Pages (JSP)
- When are JSPs useful?
- JSPs are HTML pages that imbed Java. This means
you can use a language like Java to build
structured HTML pages, reducing the amount of
code dramatically. - If you think about it, JSPs are the
implementation of application partitioning.
Presentation is done with HTML. Logic is done in
Java. - Because a significant portion of your code is in
Java, it is reusable, improving maintenance.
68JSPs are HTML!!!!
- lthtmlgt
- ltheadgtlttitlegtCustomer List lt/titlegtlt/headgt
- ltbodygt
69Special Tags add new capabilities
- lt_at_ page import"org.omg.CORBA.ORB" gt
- lt_at_ page import"org.omg.CosNaming.NamingContext"
gt - lt_at_ page import"org.omg.CosNaming.NamingContextHe
lper" gt - lt_at_ page import"org.omg.CosNaming.NameComponent"
gt - lt_at_ page import"P3_Sales." gt
70Some Java code sets things up
- lt
- String sz_action
- String sz_context
- String sz_browser
- sz_action (String)request.getParameter("obj_act
ion") - if ( sz_action null)
-
- sz_action ""
-
- sz_context (String)request.getParameter("obj_co
ntext") - if ( sz_context null)
-
- sz_context ""
-
71Then, prepare to connect and call
- bo_customer iCustomernull
- String sznew String("")
- java.util.Properties props new
java.util.Properties() - props.put("org.omg.CORBA.ORBClass",
"com.sybase.CORBA.ORB") - props.put("com.sybase.CORBA.NameServiceURL",
"iiop//localhost9000") - ORB orb ORB.init((String) null, props)
72Try to Connect
- try
- NamingContext context NamingContextHelper.narr
ow(orb.resolve_initial_references("NameService"))
- NameComponent name new NameComponent("P3_S
ales/bo_customer", "") - SessionManager.Factory factory
SessionManager.FactoryHelper.narrow(context.resolv
e(name)) - iCustomer bo_customerHelper.narrow(factory.cre
ate("jagadmin","")) -
- catch (org.omg.CosNaming.NamingContextPackage.Not
Found aException) - catch (org.omg.CosNaming.NamingContextPackage.Can
notProceed aException) - catch (org.omg.CosNaming.NamingContextPackage.Inv
alidName aException)
73Execute your PB Function
- try
- sz iCustomer.of_getcustomers_html( )
-
- catch (Exception aException)
74Send the output back to the browser
75End inline Java Code
76And, its still HTML
77Its a very small world
- lthtmlgt
- ltheadgtlttitlegtCustomer List lt/titlegtlt/headgt
- ltbodygt
- lt_at_ page import"org.omg.CORBA.ORB" gt
- lt_at_ page import"org.omg.CosNaming.NamingContext"
gt - lt_at_ page import"org.omg.CosNaming.NamingContextHe
lper" gt - lt_at_ page import"org.omg.CosNaming.NameComponent"
gt - lt_at_ page import"P3_Sales." gt
- lt
- String sz_action
- String sz_context
- String sz_browser
- sz_action (String)request.getParameter("obj_act
ion") - if ( sz_action null)
-
- sz_action ""
-
78Third Party Software
- If you find software that performs a task for
you, you can use it in EAServer, and you can
interchange them - EAServer supports Active-Xs and Java components
- Real World Example
- Image Processing solution used Active-X Single
Threaded - Changed over to multi-threaded Java class
- Changed Image Processing time from 6 minutes to
12 seconds. - Real World Example
- Needed Secure Socket connection to a TCP Server
- Active-Xs found did not give us the flexibility
we wanted - Wrote a Java class to perform SSL based
communications - Real World Example
- Needed access to MapQuest data from our
application - Used MapQuest Active-X control via OLE
79EJBs
- PowerBuilder 8 can access EJBs directly
- PowerBuilder as a Client Application can access
EJBs on non-Sybase Application Server (eg BEA
WebLogic) - Opens up a whole new world of software components
that can be integrated together - Is this really happening?
- Check out BEA Website for article on connecting
PB Apps to WebLogic components. Apparently BEA
thinks its happening.
80Other
- There are some significant components already in
EAServer that are written in Java. You can use
these today and not learn a single Java
instruction - ThreadManager for Multi-Threaded components
- MessageService for Pub-Sub messaging
- Etc
81Review
- We reviewed what J2EE was and where it was going
- We dug deeper into Servlets and JSPs and saw how
they can be leveraged to provide Browser access
to our components, be they Java or PB - We reviewed that Java Stubs are necessary to talk
to PowerBuilder from servlets or JSPs.
82Conclusions
- Java is a little more difficult to learn than a
lot of people are saying - Java is not yet the programming worlds salvation
- Java does a lot of things in standard objects
that PB doesnt have, especially in the world of
the web - PB does things that Java doesnt do, or do as
well, such as client applications in general and
Datawindows in particular - A combination of the two makes for a Powerful cup
o Joe
83Sybase PowerBuilder and EA Server - A Real
Distributed Solution
Enterprise Application Server
84Questions?
- More Info www.power3.com
- eMail Me wgreen_at_power3.com