Monday, September 26, 2011

Multi-Protocol (Oracle NCA/Web) Tips & Tricks



























Pre-Patch 4 Architecture



Figure 1: Pre-Patch 4 Architecture


General overview:

At runtime, Oracle Forms Services consists of two separate components, where each of them runs as a separate process on the server machine:

1.      Forms Listener
  1. Creates a network endpoint on a port and goes into a wait state until it receives a network request from a client machine.
  2. Upon receiving the network request, the Forms Listener process creates a new Forms Server process.
  3. Passes the details of the network connection to the Forms Server Runtime process.

2.      Forms Server Runtime
  1. Assumes the client connection from the Forms Listener process and maintains the connection with the client for the duration of the Forms application session.
  2. Uses a persistent connection to the client to send information in the form of structured messages about the running application, indicating what the client needs to display for the end user.
  3. The client uses the same persistent connection to send structured messages back to the Forms Server Runtime process, indicating actions that the end user has performed.







Pre-Patch 4 Architecture issues for Internet Deployment of Forms


Although most Forms deployment scenarios benefit from the HTTP connection mode of the Oracle Forms Server, there are some known shortcomings with the architecture:

1.                  Because the Forms Listener process manages the initial connections from the client, the machine on which the Forms Listener process is running must be exposed at the firewall level. In addition, the port that the Forms Listener process is listening to must also be exposed.

2.                  Once a client connection is handed to a Forms Server Runtime process, the client and the Forms Server Runtime process expect the connection to be persistent – that is, the network endpoints must be maintained. If the network connection at either end is dropped, the end user experiences a significant interruption and has to restart the application.

3.                  Because the data being passed uses HTTP, the Forms Listener/Server processes really become HTTP servers. Handling the slightly different HTTP formats sent by different browsers, proxies, and firewalls requires changes in the processes themselves.

 Forms Listener Servlet – patch 4


Figure 2: Post Patch 4 Architecture (using Forms Listener Servlet)


The Forms Listener Servlet is a Java servlet introduced in Oracle Forms 6i patch 4 that improves upon the functionality of the Forms Listener.  The Forms Listener Servlet requires the Oracle 9i Application Server. The Forms Listener Servlet manages:

1.      The creation of a Forms Server Runtime process for each client.

2.      Network communications between the client and its associated Forms Server Runtime process.

The Forms 6i Listener Servlet was designed to allow a more robust and standard deployment of Forms applications on the Internet.  When compared to the Forms Listener, the Forms 6i Listener Servlet provides the following benefits:

·         Broader range of firewalls and proxies supported
  • No protocol restriction (HTTP/1.1 or HTTP/1.0)
  • No extra process to manage
  • No specific certificate to purchase/manage for SSL deployment
  • Standard load balancing support
  • Internet Explorer 5.x with native JVM support

Recording a Multi-Protocol NCA/Web Script


1.      Go to VuGen and click on File à New.
2.      Select “New Multiple Protocol script.” For LoadRunner 7.51 or below, select “Create Virtual User script to record multiple protocols.” If this option is not available, please refer to How to enable Multi-Protocol recording in LoadRunner 7.5 and LoadRunner7.51.

3.      For HTTPS recording do the following:

a.       Select ONLY Oracle NCA and transfer it to the right.  Click <OK>.
b.      Click on "Options" in the Start Recording window and go to the script tab.
c.       Under Basic Options, CHECK “Generate recording log.”
d.      Go to the Port Mapping tab.  Delete the current entry for port 443, add a new entry, and put only the following:

Target Server
Oracle Forms Server’s IP address or long host name
Target Port
443
Service ID
HTTP
Connection Type
SSL    
SSL Version
Select the version you are using. If in doubt, select SSL 2/3.
     
4.      For all other recordings do the following:

a.   Select BOTH Oracle NCA and Web Protocol and transfer them to the right.  Click <OK>.
b.   Click on "Options" in the Start Recording window and go to the script tab.
c.   Under Basic Options, UNCHECK "Generate code for protocol dependencies" and CHECK “Generate recording log.”
d.      Go to the Port Mapping tab.  Click on “New Entry” and fill in the following details:

Target Server
Oracle Forms Server’s IP address or long host name
Target Port
Port for Oracle Forms server
Service ID
HTTP
Connection Type
Plain
                       










Replaying a Multi-Protocol NCA/Web Script


1.      The following information is for any type of Multi-Protocol (NCA/Web) script.

a.       If the script recorded a dynamic value called icx_ticket, then you need to correlate it.

Example:
web_reg_save_param("icx_ticket", "LB=TICKET=", "RB=&RES",  LAST);

web_url("OracleConfigure.render",
"URL=http://ABC-123:9002/pls/VIS/OracleConfigure.render\?p_page_id=2598&p_mode=0", LAST);

web_url("fnd_icx_launch.runforms",
"URL=http://ABC-123:9002/pls/VIS/fnd_icx_launch.runforms\?ICX_TICKET=<icx_ticket>&"
"RESP_APP=AR&RESP_KEY=RECEIVABLES_MANAGER&SECGRP_KEY=STANDARD", LAST);

web_url("f60cgi", "URL=http://ABC-123:9002/dev60cgi/f60cgi\?lang=US&env=NLS_LANG=” “\'AMERICAN_AMERICA.Q123456O987\'+FORMS60_USER_DATE_FORMAT=\'DD-MON”
“-RRRR\'+FORMS60_USER_DATETIME_FORMAT=\'DD-MON-RRRR%20HH24%3AM"
                                                                             "I%3ASS\'+NLS_DATE_LANGUAGE=\'AMERICAN\'+NLS_SORT=\'BINARY\'+NLS_NUMERIC_””CHARACTERS=\'.,\'&form_params=+config=\'fluffy_vis\'+icx_ticket=\'<icx_ticket>\'+resp=\'AR%2””FRECEIVABLES_MANAGER\'+secgrp=\'STANDARD\'", LAST);

lr_think_time(15);

connect_server("123.45.789.12", "9002", "module=/u0/oracle/visappl/fnd/11.5.0/forms/US/FNDSCSGN” “userid=APPLSYSPUB/PUB@VIS” “fndnam=apps config=\'fluffy_vis\' icx_ticket=\'<icx_ticket>\'”
“resp=\'AR/RECEIVABLES_MANAGER\' secgrp=\'STANDARD\' ::NLS_LANG=\'AMERICAN” “_AMERICA. Q123456O987\' FORMS60_USER_DATE_FORMAT=\'DD-MON-RRRR\'” “FORMS60_USER_DATETIME_FORMAT=\'DD-MON-RRRR HH24:MI:SS\'” “NLS_DATE_LANGUAGE=\'AMERICAN\' NLS_SORT=\'BINARY\' NLS_NUMERIC_CHARAC"
TERS=\'.,\'");

Note: The left and right boundary of the web_reg_save_param may be different depending on the application.  Below is an example of what should be captured by the web_reg_save_param.  The left and right boundaries are in bold.

Results from the execution log:
Actions.c(13):  <A HREF="javascript:top.main.icx_nav_window('WWK', 'http://ABC-123.com:9002/pl
Actions.c(13):  s/VIS/fnd_icx_launch.runforms?ICX_TICKET=5843A55058947ED3&RESP_APP= Actions.c(13):  OFA&RESP_KEY=ASSETS_VISION_OPERATIONS&SECGRP_KEY=STANDARD',\n
Actions.c(13):  'Assets, Vision Operations (USA)')" TARGET="_top" onMouseOver="window.status='Oracle
Actions.c(13):   Assets Manager, Vision Operations';return true">Assets, Vision Operations (USA)</A>\n
Actions.c(13):   </td></tr>\n

b.      For some applications, a web_url request similar to the following may be recorded multiple times inside the script.  The duplicated requests are not needed for replay, and in some cases, it might cause problem. The work-around is to comment out or delete these requests.

EXAMPLE:
/* web_url("RunformBundle_en_GB.properties", "URL=https://ABC-123:9002/forms60java/oracle/forms/engine/RunformBundle_en_GB.properties", LAST); */
2.      For an HTTPS script
Add the following at the beginning of the script if the replay fails at the connect_server.
web_set_sockets_option("SSL_VERSION","3");

3.      For a Servlet script
VuGen should automatically generate a web_reg_save_param to correlate the dynamic value of JservSessionIdroot.  If this function is not generated automatically, then you may need to insert it manually.

Example:
      web_reg_save_param("NCAJServSessionId","LB=\r\n\r\n","RB=\r","ORD=1",LAST);

web_url("f60servlet",
               "URL= http://ABC-123/servlet/oracle.forms.servlet.ListenerServlet?ifcmd=getinfo&” “ifhost=mercury&ifip=123.45.789.12", LAST);

Note: 
  1. The left and right boundaries of the web_reg_save_param may be different depending on the customer’s application.  What we have seen is sometimes the right boundary is \n instead of \r.  Below is an example of what should be captured by the web_reg_save_param (bold).  The left and right boundaries are in blue.

Example: From the execution log:
vuser_init.c(8): 297-byte response headers for "http://ABC-123/servlet/oracle.forms.servlet.ListenerServlet?ifcmd=getinfo&ifhost=mercury&ifip=123.45.789.12" (RelFrameId=1)
vuser_init.c(8):     HTTP/1.1 200 OK\r\n
vuser_init.c(8):     Date: Tue, 15 Jan 2002 18:17:34 GMT\r\n
vuser_init.c(8):     Server: Oracle HTTP Server Powered by Apache/1.3.19 (Win32) mod_ssl/2.8.1 OpenSSL/0.9.5a m
vuser_init.c(8):     od_fastcgi/2.2.10 mod_oprocmgr/1.0 mod_perl/1.25\r\n
vuser_init.c(8):     Set-Cookie: JServSessionIdroot=my1sanw2n1.JS4; path=/\r\n
vuser_init.c(8):     Content-Length: 79\r\n
vuser_init.c(8):     Content-Type: text/plain\r\n
vuser_init.c(8):     \r\n
vuser_init.c(8): 81-byte response body for "http://ABC-123/servlet/oracle.forms.servlet.ListenerServlet?ifcmd=getinfo&ifhost=mercury&ifip=123.45.789.12" (RelFrameId=1)
vuser_init.c(8): /servlet/oracle.forms.servlet.ListenerServlet?JServSessionIdroot=my1sanw2n1.JS4\r\n
vuser_init.c(8): Saving Parameter "NCAJServSessionId = /servlet/oracle.forms.servlet.ListenerServlet?JServSessionIdroot=my1sanw2n1.JS4"

  1. You may need to manually insert the parameter "NCAJServSessionId” in later web_url requests that refers to the JservSessionIdroot dynamic value. 

Example:
web_reg_save_param("NCAJServSessionId","LB=\r\n\r\n","RB=\r","ORD=1",LAST);

web_url("f60servlet",
               "URL= http://ABC-“123/servlet/oracle.forms.servlet.ListenerServlet?ifcmd=getinfo&” “ifhost=mercury&ifip=123.45.789.12", LAST);

web_url("oracle.forms.servlet.ListenerSer",
               "URL=http://ABC-123<NCAJServSessionId>?ifcmd=getinfo&” “ifhost=mercury&ifip=123.45.789.12", LAST);

connect_server("123.45.789.12", "9002", "module=/u0/oracle/visappl/fnd/11.5.0/forms/US/FNDSCSGN” “userid=APPLSYSPUB/PUB@VIS fndnam=apps record=names");

  1. If during replay you do not see the value of JServSessionIDRoot as saved into your script’s parameter, then the connect string may be hard-coded. To resolve the issue,

i.        Close the script.
ii.      Navigate to the script directory, and edit default.cfg using word editor
iii.    In the section [HttpConnectMode], modify the line for RelativeURL= to refer to the correlated NCAJservSessionId.

Example:
Change from

RelativeURL=/oracle.forms.servlet.ListenerServlet/Session?JServSessionIdroot=yklxp0

To

RelativeURL={NCAJservSessionId}

Note: For LoadRunner7.6, use RelativeURL=<NCAJservSessionId>.




















Correlating a Multi-Protocol NCA/Web Script


Sometimes the information returned from an NCA function is needed in the web_url request following it.  This is particularly true with Oracle Configurator applications.  Depending on what type of an NCA object it is, you may use either the edit_get_text or the java_get_value function to capture the dynamic string.

1. edit_get_text

a.       If the data you want to retrieve has the object name or ID recorded in the script, then simply use it in the edit_get_text function.

Example:
//Recorded functions
set_window( "Oracle Applications");
edit_set("FNDSCSGN.SIGNON.USERNAME.0","SYSADMIN");
obj_type("FNDSCSGN.SIGNON.USERNAME.0",'\t',0);
//The following lines will capture the value of the username from the edit field.
Char val[25];
edit_get_text("FNDSCSGN.SIGNON.USERNAME.0",val);
lr_output_message ("The username is %s", val);

b.      If the data you want to retrieve does not have the object name or ID recorded in the script, then you have to look for the object ID. To do so, you need to
i.        Replay the script with extended logging.
ii.      Search for the name/ID of the field or search for the expected value in the execution log.
iii.    Get the handlerID.
iv.    Use the edit_get_text function to retrieve the value of the handlerID.

Example: After clicking on the  “Refresh Data” button, the status appears in the “Phase” column. However, these fields cannot be clicked on and therefore nothing is recorded.





     Sample script recorded:

set_window( "Submit Request");
button_press("FNDRSRUN.WORK_ORDER.SUBMIT.0");
set_window( "Requests");
button_press("FNDRSRUN.JOBS.REFRESH.0");

To retrieve the Object ID from the "Phase" status column, and to find out whether it is "Inactive" or "Active"

1.      Put the cursor at the very beginning of the execution logs and searched for "Inactive."  If you do not find it, then search for “Active.”

Example:
Action1.c(42):       property=137 type=0x4000 value="Inactive"

2.      Look above the line found on step i. You will see that there is a handlerID.  This handlerID is equivalent to the Object ID in Oracle NCA, and it is the value to retrieve.

Example:
Action1.c(42): Server Message Properties: action=2  handlerClassId=0x101  handlerId=397
Action1.c(42): property=137 type=0x4000 value="Inactive"

3.      In the script, go to the line number specific in the () . For this example, it is line 24. The sample script in this cause lead us to a line with the following information:

button_press("FNDRSRUN.WORK_ORDER.SUBMIT.0");

4.      Use the edit_get_text function to retrieve the value.

Example:
char value[25];
button_press("FNDRSRUN.WORK_ORDER.SUBMIT.0");
edit_get_text("397", value);
lr_output_message ("The phase of Journal Import is %s", value);


2. java_get_value

Use the java_get_value when the handlerClassID return the value 0x10F, which means that the object is java.

Example:
Actions.c(15):       Sub Message Properties: action=2  handlerClassId=0x10F  handlerId=458
Actions.c(15):  property=403 type=0x4000 value="+"
Actions.c(15): property=404 type=0x4000 value="CFG:oracle.apps.cz.javaRenderer.BACfgClient:managerURL=http\//merc-int.com\8000/configurator/oracle.apps.cz.servlet.UiServlet:xmlAction=<initialize><param name="terminate_msg_behavior">brief</param><param name="database_id">eprdhe1_opr1</param><param name="context_org_id">181</param><param name="config_creation_date">12-14-2001-11-11-31</param><param name="calling_application_id">660</param><param name="responsibility_id">50397</param><param name="model_id">294699</param><param name="ui_type">Applet</param>></initialize>"
Actions.c(15): Server Message Properties: action=2  handlerClassId=0x101  handlerId=635
Actions.c(15):             property=131 type=0x4000 value="1"

To capture the dynamic value ( 12-14-2001-11-11-31 ) above, you need to save the entire information into a string using java_get_value, then parse through the buffer and capture the dynamic values using lr_save_searched_string.  For detail implementation:

1.      In order to use the java_get_value function, you must know the name of the Java object that is returning these dynamic values.  To find out the name of the Java object, look at the handlerID number next to the handleclass. In sample above, the handleID is 458 (… handlerClassId=0x10F  handlerId=458…).

2.      Search for the first occurrence of the handleID found in step 1 in the execution log. You will see something similar to the following.

3.      Example:
vuser_init.c(8): Server Message Properties: action=1  handlerClassId=0x10F  handlerId=458
vuser_init.c(8):    property=134 type=0x3000 value=406
vuser_init.c(8):    property=135 type=0xA000 value=Point [x=417,y=458]
vuser_init.c(8):    property=137 type=0xA000 value=Point [x=0,y=6]
vuser_init.c(8):    property=168 type=0x7000 value=1
vuser_init.c(8):    property=129 type=0x4000 value="ORDER_CONTROL_0"
vuser_init.c(8):    property=397 type=0x4000 value="oracle.apps.fnd.formsClient.AppletAdapter"

4.      Search for property=129 (which stands for title), you should find the name of the Java object. In the sample above, the value is ORDER_CONTROL_ 0.

5.      Correlate using java_get_value function.

Example:
Char out_value[200];
button_press("ORDER_CONTROL_CONFIGURATOR_0");
java_get_value("ORDER_CONTROL_0", out_value);

6.      To verify if java_get_value is working, replay the script then check the execution log. You should see the value captured.

Example:
Actions.c(8): java_get_value("ORDER_CONTROL_ 0","CFG:oracle.apps.cz.javar….")

7.      Now, use the lr_save_searched_string to search for the dynamic values saved into out_value buffer. The sample below explains how to capture the dynamic value of config_creation_date and use it in the following web_url.

lr_save_searched_string(out_value,100, 0, "config_creation_date\">",0,19, "config_date");

web_url("oracle.apps.cz.servlet.UiServlet",
"URL=http://merc-int.com:8000/configurator/oracle.apps.cz.servlet.UiServlet\?getUiType=”
”%3Cinitialize%3E%3Cparam+name%3D%22terminate_msg_behavior%22%3Ebrief%3C%2F””param%3E%3Cparam+name%3D%22database_id%22%3Eeprdhe1_opr1%3C%2Fparam%3E””%3Cparam+name%3D%22context_org_id%22%3E181%3C%2Fparam%3E%3Cparam+name%3D%22config_creation_date%22%3E<config_date>%3C….",
LAST);

Tips and Tricks

Q.  What version of LoadRunner supports Multi-Protocol NCA/Web script?

R.     LoadRunner 7.5 and above.

Q.  How to enable Web replay’s Run-Time Settings.

For LoadRunner 7.5 and 7.51 Multi-Protocol NCA/Web, there is no tab for “Browser Emulation.” This causes two major problems:
1.      By default, "Simulate a new user each iteration" is enabled.  If user recorded login in the vuser_init and logoff in the vuser_end section, it will cause the script to fail when user iterate the script.  The replay will fail with a message similar to the following:
Actions.c(4): t=53828ms : Server 123.456.78.123 has shut down connection
2.      By default, "Download non-HTML Resources" is enabled.  This causes the Oracle JInitiator to be downloaded each time the user replay the script.  Sometimes this will cause the replay to take a long time (10-30 minutes).  In severe cases, it will try to install the JInitiator.
R.     Add the tab for “Browser Emulation” to the Run-Time Settings:
1.      Close the script.
2.      Go to <LoadRunner>\dat and bring up vugen.dat in a word editor.
3.      Search for the [Multi] section.
4.      On the line for cfg_tab_dll=, add LrwRunTimeSettingsUI.dll.

Example:
      cfg_tab_dll=comrts_tab.dll, LrwRunTimeSettingsUI.dll

5.      If you launch the script again in VuGen, the “Browser Emulation” tab is now available. You need to:
·         Clear the "Download non-HTML Resources" cehckbox.
·         Clear the setting for  "Simulate a new user each iteration."

Q.  When to use Multi-Protocol Oracle NCA/Web.

R.     Multi-Protocol should be used if any of the following conditions apply:
  1. To record against Oracle Forms 9iAS.
  2. To record against an HTTPS NCA application.
  3. To record against an NCA server using Forms Listener Servlet.
  4. To record against an NCA application where part of it uses HTTP communication (e.g. Oracle Configurator and Oracle Demand Planner modules).
  5. To record against the initial HTTP startup to simulate load balancing.

Q.  How to enable Multi-Protocol in LoadRunner 7.5 and LoadRunner7.51.

R.     Follow the steps below to enable Multi-Protocol:
a.       Go to the Windows root directory (e.g., C:\winnt) and open the vugen.ini file.
b.      Go to the [General] section.
3.   Add the following below this section:
      EnableMulti=1

Q.  How to replay a Multi-Protocol NCA/Web script on Unix.

R.     Replay of Multi-Protocol NCA/Web script on Unix is supported by default on LoadRunner 7.51 or above. For LoadRunner 7.5, however, you need to make the following changes:

1.   Copy the attached Vugen.dat file to your Controller machine.  The file should go into the <LoadRunner>\dat folder.

2.   Copy the attached mdrv_nt.dat file to your Controller machine.  The file should go into the <LoadRunner>\dat directory.  Rename the file to mdrv.dat after it has been copied over.

3.   Copy the attached mdrv_unix.dat file to your Unix machine.  The file should go into the <LoadRunner>\dat directory.  Rename the file to mdrv.dat after it has been copied over.

4.   You need to close the Controller and restart it after copying all the files over.

Q.  Error: "The formsLauncher failed to connect to the existing forms session properly…” on recording

R.     This is a recording problem that has been addressed in LoadRunner7.8. If you are using LoadRunner7.6 or lower, you can use the following workaround:

1. Go to the recording options -> Network: Port Mapping
2. Click on new Entry
3. Enter the recording machine name in "Target Server" field and 0 in "Port" field, click on Update
4. In Port mapping window, uncheck this new entry and click on OK to quit.
5. Start recording.

Un-checking the server will make sure that NCA/WEB recorder do not trap the communication, assuming that the information is not important. If this does not help, please contact Mercury Interactive Customer Support.


No comments:

Post a Comment