Download Document

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Application Modernization:
Brotherhood Mutual Insurance Co.’s
Claims Application
Mike Prinster – Sirius Computer Solutions
[email protected]
Goals of the Claims System
• “Create a graphical interface for the
current claims system.”
• All business logic, whether existing or
new, must reside in RPG code.
• Users will interact with the Claims
system using a web browser.
The Players
• DB2 on iSeries Database
• RPG for Business Logic
• IBM Toolbox for Java for Java-to-RPG
communications
• Java and Struts on WebSphere Application
Server on the iSeries for user interface
• Presentation
Layer
• Business
Logic
Abstraction
Layer
• iSeries
Business
Logic Layer
(RPG)
“Show me
claim #123…”
Presentation Layer
• Struts Web Application Framework
• Model-View-Controller (MVC) Architecture
• We won’t spend much time here tonight…
Business Logic Abstraction Layer
• Facades hide details from higher-level layers
• Facades manage RIO interactions, iSeries
connections
• RIOs encapsulate 1+ RPG method calls
iSeries Business Logic Layer
• RPG Request Broker receives all calls from
Java, delegates to appropriate RPG program(s)
• Information exchanged with Java via PCML
calls or on data queue (or both)
A Day In The Life of a RIO
Java reflection, IBM
Toolbox for Java and
XML used to place
values on data queue
RPG Invocation
Object
Return code and parms
sent back to invoking Java
method that called PCML
(e.g. error, success)
Return
Invoke
PCML used to
invoke RPG broker
via IBM Toolbox
for Java
Java Reflection, IBM
Toolbox for Java and
XML used to retrieve
values from data queue
RPG Request Broker
Broker invokes
designated RPG
program
RPG Program
RPG program returns
response and/or places
values on data queue
Boy, that’s a lot of layers!
• If you anticipate only a few RPG-Java
interactions, a framework like Claims’ is
more than you need (Claims has over 100)
• If you anticipate many projects, each with a
few RPG-Java interactions, you’ll still end
up ahead in the long run with a framework
• If performance is a requirement, consider a
framework (more on this later)
Claims Architecture Benefits
• “But the wizard in WDSc takes two minutes!”
• iSeries connection pooling for performance
• Standardized, repeatable solution – adding
each new RPG-Java interaction is
straightforward once framework is in place
• Can swap out or add technologies on the
lower layers without breaking the system
• Robust performance: over 99% uptime
Thank you!
Questions?
[email protected]
Hurdles of Java Development
Robin Anglin
[email protected]
November 8, 2005
Hurdles
• MVC Architecture
• Java Inheritance
• Java Multi-Threading
Model / View / Controller
Architecture
MVC – Model
Controller
Model
Manages data
• Java Beans
• IBM Toolbox
View
MVC – View
Controller
Model
Manages data
• Java Beans
• IBM Toolbox
View
Graphical
presentation
• Java Server
Pages
MVC – Controller
Controller
Connects Model
with View
• Struts
• Java Server
Faces
Model
Manages data
• Java Beans
• IBM Toolbox
View
Graphical
presentation
• Java Server
Pages
MVC – Transitioning from RPG
View
Model
B001
001
001
001
B002
002
B003
?***************************************************
?* CALL PROGRAM TO DISPLAY THE TERRITORY HELP MEMBER
?***************************************************
Ftblste
if
e
k disk
Fdf0807
cf
e
workstn
D @spl
s
1
D @tpgm
s
6
D member
s
10
*
C
dou
*in01 = *on
C
move
'P'
@spl
C
exfmt
disply
C*
C
if
*in01 <> *on
C
@sstno
chain
tblste
C
if
*in99 = *on
Controller
Java Inheritance
Inheritance – Objects
Cycle
Wheel
Pedal
Must have
2 pedals
“is a” relationship (extends)
Tricycle
Wheel
Pedal
Must have
2 pedals
Handlebar
Inheritance - Risk
Claim Façade
getWorkersCompPageSetup()
getCasualtyPageSetup()
getPropertyPageSetup()
BaseRIO
PolicyBasicRIO
Before
StatRIO
Inheritance - Risk
Claim Façade
getWorkersCompPageSetup()
getCasualtyPageSetup()
getPropertyPageSetup()
BaseRIO
PolicyBasicRIO
After
StatRIO
GenericCoverage
ExtRIO
Java Multi-Threading
Single Threading
• Single stream of execution
Enter check information
Print check
Update check register
Multi-Threading
• More than one stream of execution
Enter check information
Print check
Update check register
Multi-Threading
Selected Entries
Coverage Extension Description
Antennas
0101 Church
Cause of Loss
Breakage-M1
Next >
(invokes PropertyAction class)
Set Reserves
Line Cause
Description
<INPUT type=“submit" name="Next"
value="Next &gt;"
class="bmiButtonText"
onclick="return
doSubmit('Next',this.form)">
Hurdles
• MVC Architecture
• Java Inheritance
• Java Multi-Threading
Resources
• Books
Java Design Building Better Apps & Applets
By Coad, Mayfield, & Kern, Yourdon Press
Java Server Faces in Action
By Kito Mann, Manning Publications
Struts in Action
By Husted, Dumoulin, Franciscus, & Winterfeldt,
Manning Publications
Resources
• Favorite Websites
Apache Struts
http://struts.apache.org/index.html
IBM developerWorks
http://www-130.ibm.com/developerworks/
Java Technology
http://developer.java.sun.com/
The ServerSide
http://www.theserverside.com/tss
Role Playing Games
Jared Gerber
[email protected]
260-481-9906
November 8, 2005
A Holistic View
• My job is a whole lot more than writing code
• This project has taught me a lot about …
– Insurance claims and how they work
– The inter-continental office
– Using a methodology to develop a system
– User designed applications
– Project tracking and coordination
• The process is as important as the product
Session ID
User ID
Request/Action
Key Type
Key Value
Status
Message
# of DQ Entries
32A
10A
32A
10A
24A
1A
64A
5A
Unique to each browser session
Derived from LDAP and passed by Java
This tell the Broker program what to do
Indicates the type of key value being passed
Actual key value being passed
E,W,I,S (see note)
Detail informational message
Number of entries in the data queue
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- Get single claim detail for agent in uc71 -->
- <request name="getAgencyClaimDetail" cached="false" UC="71">
<requestDesc>Get Agent Claim Detail</requestDesc>
- <pcml fileName="claimsBase">
<parm keyType="agencyID (format: nnnn) or *ALL (to disregard agencyid for BMI
users)" optional="false" />
<parm keyValue="ClaimNumber (format: nnnnnn)" optional="false" />
</pcml>
-<rfml fileName="fieldMap.xml">
<!-- Return agent claim. -->
<retrieveDQ struct="agentClaimDetail" key="claimDetail" layout="DQCRAGTCLM" />
<!-- Return list of claim payments. -->
<retrieveDQ struct="agentPayment" key="payment" layout="DQCRAGTPMT" />
<!-- Return list of claimants. -->
<retrieveDQ struct="agentClaimant" key="claimant" layout="DCCRAGTCMT" />
<!-- Return list of Generic Descriptions for vehicle or property, etc. -->
<retrieveDQ struct="genericDescription" key="genericDescription"
layout="DQCRGENDSC" />
<!-- Return list of drivers for auto claims -->
<retrieveDQ struct="text" key="drivers" layout="comma separated (1000 bytes)" />
</rfml>
</request>
Key Elements
• Consistent interface
(Broker program)
• Interface document (contract between Java
and RPG)
RPG Coding Standards
•
•
•
•
•
•
•
•
•
•
•
•
•
These were in addition to current shop standards
New programs were written /free
Created pgms using a named activation group (QILE)
Prototyped all calls, procedure, & *entry parms (D-specs)
No key lists
chain (state:type:policy#) polhdr;
Each program would do one and only one task
Made every effort to keep main logic concise
Introduced Date and Timestamp fields to database
Introduced Varying Length fields
Extensive use of BIF’s
Required code to be efficient
Implemented Peer Code Reviews
Modular, reusable, top down flow
/TITLE Claims Get Generic Cause of Loss
*=====================================================================
* Compile with DFTACTGRP(*NO) ACTGRP(QILE) BNDDIR(BMIBNDDIR)
*=====================================================================
* Program runs in an environment that Shares Open Data Paths
*=====================================================================
**********************************************************************
* Program:
OL0549
* Description: Claims Get Generic State Abrv and Name - getGenStates
*
**********************************************************************
Ftblstal2 if
e
k disk
*=====================================================================
* Prototype for Input Parameters (*ENTRY replacement)
*=====================================================================
d ol0549
pr
extpgm('OL0549')
d
178
d ol0549
pi
d Linkage
178
*=====================================================================
* Prototype for Calls to External Programs
*=====================================================================
* API to Send Data to Data Queue
d qsnddtaq
pr
extpgm('QSNDDTAQ')
* Data Queue Name
d
10
* Data Queue Library
d
10
* Data Sent Length
d
5 0
* Data Sent
d
1024
* Data Queue Key Length
d
3 0
* Data Queue Key
d
64
*=====================================================================
* Linkage Structure and Format Data Structures
*=====================================================================
d Prog_parms
e ds
extname(CRBROPARMS)
d GenericDescDS e ds
extname(DQCRGENDSC)
*=====================================================================
* Procedure Prototypes
*=====================================================================
* File Procedures
/Define ProtoOnly
/Copy *libl/qrpgsrc,mdstring
*=====================================================================
* Work Variables
*=====================================================================
D quenam
s
10
inz('CRDTAQ')
D quelib
s
10
inz('*LIBL')
D datalen
s
5 0
D data
s
1024
D keyLen
s
3 0
D key
s
64
D dqcount
s
5 0
d errors
s
n
/free
// ==============================================================
// Main Process
// ==============================================================
Prog_parms = linkage;
dqcount = *zeros;
setll *loval tblstal2;
dou %eof(tblstal2);
read tblstal2;
if %eof(tblstal2);
leave;
endif;
gndesc
gnkey
= PropCase(stname);
= stabrv + %editc(stnumb:'X');
// Fix mixed case issues
if stname = 'WASHINGTON DC';
%subst(gndesc:13:01) = 'C';
endif;
// Put data in data queue
datalen
= %len(GenericDescDS);
data
= GenericDescDS;
keylen
= 64;
key
= p_sesID + 'GenericStates';
callp(e) qsnddtaq(quenam:quelib:datalen:data:keylen:key);
if %error;
eval errors = *on;
P_Status
= 'E';
P_Msg
= 'Error putting data in Data Queue';
leave;
endif;
dqcount = dqcount + 1;
enddo;
if not errors;
p_status = 'S';
P_msg
= *blanks;
p_dqent
= %editc(dqcount:'X');
endif;
linkage = Prog_parms;
return;
/end-free
RPG Concepts and Approaches
• Each program satisfies an event or Java request
(gets/puts)
• Memory Resident, Reentrant (no LR) for performance
• Shared ODP (Open Data Paths) for performance
• Keyed data queues (64A)
Session ID
User ID
Request/Action
Key Type
Key Value
Status
Message
# of DQ Entries
32A
10A
32A
10A
24A
1A
64A
5A
Unique to each browser session
Derived from LDAP and passed by Java
This tell the Broker program what to do
Indicates the type of key value being passed
Actual key value being passed
E,W,I,S (see note)
Detail informational message
Number of entries in the data queue
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- Get single claim detail for agent in uc71 -->
- <request name="getAgencyClaimDetail" cached="false" UC="71">
<requestDesc>Get Agent Claim Detail</requestDesc>
- <pcml fileName="claimsBase">
<parm keyType="agencyID (format: nnnn) or *ALL (to disregard agencyid for BMI
users)" optional="false" />
<parm keyValue="ClaimNumber (format: nnnnnn)" optional="false" />
</pcml>
-<rfml fileName="fieldMap.xml">
<!-- Return agent claim. -->
<retrieveDQ struct="agentClaimDetail" key="claimDetail" layout="DQCRAGTCLM" />
<!-- Return list of claim payments. -->
<retrieveDQ struct="agentPayment" key="payment" layout="DQCRAGTPMT" />
<!-- Return list of claimants. -->
<retrieveDQ struct="agentClaimant" key="claimant" layout="DCCRAGTCMT" />
<!-- Return list of Generic Descriptions for vehicle or property, etc. -->
<retrieveDQ struct="genericDescription" key="genericDescription"
layout="DQCRGENDSC" />
<!-- Return list of drivers for auto claims -->
<retrieveDQ struct="text" key="drivers" layout="comma separated (1000 bytes)" />
</rfml>
</request>
RPG Concepts and Approaches
•
•
•
•
Each program satisfies an event or Java request (gets/puts)
Memory Resident, Reentrant (no LR) for performance
Shared ODP (Open Data Paths) for performance
Keyed data queues
• Limited use of old code
• Imbedded SQL
– SQL on iSeries was new to shop
– Primarily used for searches (programs written by Sirius
consultant)
– A real life saver
Testing
• Simple in the sense that if the data queue entries were
right, you passed
• Need to simulate a request to the broker
• Viewing data queue entries (pass/fail)
• Memory resident/reentrant so you need to reclaim
activation group if you recompile
• Complex data queue entries usually needed Java
programmer involvement
PGM
/* Test Broker */
/*===================================================================*/
/* Program variables:
*/
DCL
VAR(&P1) TYPE(*CHAR) LEN(32)
DCL
VAR(&P2) TYPE(*CHAR) LEN(10)
DCL
VAR(&P3) TYPE(*CHAR) LEN(32)
DCL
VAR(&P4) TYPE(*CHAR) LEN(10)
DCL
VAR(&P5) TYPE(*CHAR) LEN(24)
DCL
VAR(&P6) TYPE(*CHAR) LEN( 1)
DCL
VAR(&P7) TYPE(*CHAR) LEN(64)
DCL
VAR(&P8) TYPE(*CHAR) LEN( 5)
DCL
VAR(&MSG) TYPE(*CHAR) LEN(78)
/*===================================================================*/
CHGVAR
VAR(&P1) +
VALUE('WKr3zNnaoYHfCKmGhx71NQ3
')
CHGVAR
VAR(&P2) +
VALUE('JGERBER
')
CHGVAR
VAR(&P3) +
VALUE('getGenStates
')
CHGVAR
VAR(&P4) +
VALUE('
')
CHGVAR
VAR(&P5) +
VALUE('
')
CHGVAR
VAR(&P6) VALUE(' ')
CHGVAR
VAR(&P7) VALUE(' ')
CHGVAR
VAR(&P8) VALUE(' ')
CALL
PGM(OLCRBROKER) PARM(&P1 &P2 &P3 &P4 &P5 &P6 +
&P7 &P8)
CHGVAR
VAR(&MSG) VALUE(&P8 *BCAT &P6 *BCAT &P7)
SNDPGMMSG MSG(&MSG)
/*===================================================================*/
END:
ENDPGM