Friday, 31 January 2014

codechangecom.exe What is this?

codechangecom.exe is a slimer provided to you in your client system\bin32 dir which can be used to convert existing single byte “C” BSFN’s to unicode compliant code.

That is nice!

C:\E910_1\system\bin32>codechangecom.exe

Expected the following parameters
<input File> <outputfile> <mode>

So, what do we put in the parameters – please see https://support.oracle.com/epmos/faces/DocContentDisplay?_afrLoop=109554459225750&id=626598.1&_afrWindowMode=0&_adf.ctrl-state=76dfd0sjx_77 for all of the details, but I’ll summarise

Parameter 1:
CommandFile is a filename which contains commands for CodeChangeCom. It is not the name of a file you wish to convert. Commands in the file tell CodeChangeCom what files to convert. There are four formats for each command. Each command is a single line in the file. Here is an example command:
C:\fun\in\the\sun –r
This tells CodeChangeCom to find every .h, .c, .cpp, .hpp file in the directory c:\fun\in\the\sun, plus all the files in every subdirectory under that directory. Here is another example:
! C:\fun\in\the\sun\sunblock.c
This tells CodeChangeCom to not change the file sunblock.c in the given directory. Here is another example:
C:\fun\in\the\
This tells CodeChangeCom to change every file in the directory c:\fun\in\the\, but not any of the subdirectories of that directory. Here is the last example:
! C:\fun\in\the\sun\sand\
This tells CodeChangeCom to skip the entire directory c:\fun\in\the\sun\sand, regardless of how many files are in that directory.

Parameter 2:

This is a simple filename, which will contain the results of the operations after it has finished. If the program just reports on changes – but doesn’t actually do them, then the results are in this file.

Parameter3:
This is the word “audit” or the word “convert”. If it is “audit” then only results will be reported, no changes will be made. If it is “convert” then the code will be converted, but what is actually changed will not be recorded anywhere.

 

Wow, talk about a complicated way of doing things!  Why not param 1: filename in param 2: filename out param3: mode ????

So, I’ll create a commands.txt file with the following contents (I just want the include and the source checked)

C:\e910_1\dv910\source\b5801002.c

C:\e910_1\dv910\include\b5801002.h

Then I’ll run codechangecom.exe commands.txt changes.txt audit

 

The output I get:

========>Parsing File: \e910_1\dv910\source\b5801002.c <=======

   66: jdeErrorSet (lpBhvrCom, lpVoid, (ID) 0, "4363", (LPVOID) NULL);
----->                                         1
       1. Literal string requires enclosure in appropriate macro.

   73: memset((void *)&dsD5801000T, (int)('\0'), sizeof(dsD5801000T));
----->                                    1
       1. Literal string requires enclosure in appropriate macro.

   80:                   (char *)NULL,
----->                    1
                               (char *)NULL,
----->                          2
       1. 'JCHAR' replaces 'char'.
       2. 'JCHAR' replaces 'char'.
========>Parsing File: \e910_1\dv910\include\b5801002.h <=======

   89: char              szFunctionName[33];
-----> 1
       1. 'JCHAR' replaces 'char'.

Note that the source and include I’m parsing is VERY simple.  I don’t think that it’s important that I list the source and include – you can see  the good work that it’s done.

Next is to run it in convert mode!

Great, my code is ALL unicode – lets try a compile!

Compile works first time.  this is why you use the JD Edwards provided functions and you get to use utilities like this!

Wednesday, 29 January 2014

Oracle scripting for JD Edwards

Some tips and tricks for oracle scripting:

Have a standardised header for your scripts.  Here is a standard header and footer that I like to use.  Basic and can be augmented to what you want:

 

column filename new_val filename
select 'GenerateStats_' || to_char(sysdate, 'yyyymmdd' ) filename from dual;
spool &filename

set echo on

set timing on
select to_char(sysdate,'HH24:MI:SS') from dual;
select to_char(sysdate,'YYY MM DD') from dual;

 

Script goes here

 

select to_char(sysdate,'HH24:MI:SS') from dual;
select to_char(sysdate,'YYY MM DD') from dual;

set echo off

spool off;

quit;

Something like this will spool to the current directory and log to a filename that is unique based upon day.  that is pretty nice.  You need to use things like this when you are doing cutovers or go-lives and need auditable results.

 

SELECT 'SELECT DBMS_METADATA.GET_DDL(''' || 'INDEX''' || ',''' || index_name || '''' || ',''' || 'UAFINDTA' || ''')'  || ' FROM dual ;'
from all_indexes t1 where t1.table_owner = 'UAFINDTA'
and not exists (select 1 from all_indexes t2 where t2.table_owner = 'PYFINDTA' and t1.index_name = t2.index_name  );

Remember that catalogs and functions are your friend.  The number of cool queries that you can do over all_indexes and all_tables is limitless.  The above query will generate the statements that will generate DDL for all indexes in the UAFINDTA schema that is not in PYFINDTA.

remember to add PARALLEL clauses and also NOLOGGING if you are allowed – this’ll make index generates up to 50% quicker.

Change the oracle Logo for 9.1.X tools releases

Introduction:

You need to make these changes in the runtime directories for E1, but if you replace a tools release they’ll be gone.  I generally set up some vbs / cmd scripts that can refresh all my customisations in one fowl swoop – so that if I deploy a new tools release, all of my skinning changes can be made immediately.  Note that I also like to add new files as opposed to change existing ones, this is why I edit the two jspf files below and not just rename of the oracle_logo.png file.

Changing the oracle logo once you’ve logged in:

imageAnother sample hack.  You get the picture.  Oracle logo gone and your one in it’s place.  With some nice hover text too!

File to change:

D:\Oracle\Middleware\user_projects\domains\E1_Apps\servers\JWB01P_PDCMSAU_94\stage\JWB01P_PDCMSAU_94\app\webclient.war\WEB-INF\jsp\maflet\DropdownHttpMafletWrapperHeader

This is the new

if (!viewBean.getInOWP())

{

%>

<td id=topimagecell valign="top" class="topimagecell">

<table border="0" cellspacing="0" cellpadding="0" width="100%" class="topnavtable">

<tbody>

<tr>

<td><img id="UISp1" src="<webgui:resourceUrl resourceUrl="afr/t.gif"/>" alt="" width="4" height="0px"></td>

<td><img id="oracleImage" onclick="javascript:goHome();" alt="Myriad IT Services" width="90" height="23px" style="cursor:pointer; padding-top: 1px;"

src="<webgui:resourceUrl resourceUrl="images/rcux/myriad_logo.png"/>"></td>

<td><img id="UISp2" src="<webgui:resourceUrl resourceUrl="afr/t.gif"/>" alt="" width="3" height="0px"></td>

<td><span onclick="javascript:goHome();" style="white-space:nowrap; cursor:pointer;" class="appname" id="Sot13">JD Edwards EnterpriseOne</span></td>

<td nowrap="nowrap" align="<%=viewBean.getOppositeBaseAlignment()%>" valign="top" width="90%" class=toptext>

<table border=0 cellpadding=0 cellspacing=0 role="menubar">

<tbody>

<tr>

Changing the oracle logo on the login page:

imageSorry about the hack demo – I didn’t have time to do it nicely.  Shows you what you are changing though.

file to change.

\\webserver\d$\Oracle\Middleware\user_projects\domains\E1_Apps\servers\JWB01P_PDFIN_96\stage\JWB01P_PDFIN_96\app\webclient.war\share\loginDecoration.jspf

if ( (companyLogoImageURL != null) && (companyLogoImageURL.length() > 0) || smallScreen )

{

if (companyLogoImageURL.length() != 0)

{

sb.append("<img src=\"");

sb.append(resourceUrlBuilder.createUrl("/share/images/rcux/myriad_logo.png"));

sb.append("\" ALT=\"ORACLE &reg;\"");

sb.append(" width=\"219\" border=\"0\" height=\"75\">");

}

}

Else

Tuesday, 14 January 2014

Performance testing oracle JD Edwards EnterpriseOne JDE

I’ve done a lot of performance testing of EnterpriseOne.  Back in time I was involved in testing over 10000 users with load runner on a mix of web and citrix.  I’ve now started doing a lot of specific JD Edwards load testing using Oracle Application Testing Suite (OATS). 

Of course OATS can test all of the JD Edwards suite natively, because it’s oracle.  But it can also natively test all of the oracle product suite natively (in fact – ANY web based application).  OATs has accelerators for many of the oracle products, which make recording and reading the scripts a breeze.

Load testing itself is not overly complicated and you can execute this as a “one off” without any problems.  But how do you know what is normal? What is fast? Where improvements can be made? It’s difficult when you only have one set of performance data to use for your comparisons.  What I mean in this situation is, if you are getting average response times of .75 sec, is this good for a 400 user concurrent test?  Can you improve that?  Is 50% CPU utilisation on the database server normal with 300 users connected?  All of these questions are difficult to answer without a frame of reference.

At Myriad, we do load testing for lots of clients with lots of different architectures and we can tell what is fast and what is slow at the various application tiers.  We know where you should be putting your horsepower and we know what is going to make the best difference for your ERP performance.

So what I guess I’m saying is that you can have all of the findings and metrics in the world, but the interpretation of these results is where the value is.  I guess there is a similar analogy with big data, you can have all of the data in the world, but it means nothing until you’ve interpreted it.  It seems to me that the real value of metrics is found with interpretation & comparison rather than merely representation.  In the simplest form, your information is valuable as soon as you make a change and then compare the results.  The metrics start to have value with comparison.  This is true with your performance tuning data, you need to compare your previous results to know if you are making improvements or not, but unless you compare with industry standard benchmarks, you won’t know if there are other gains that you can easily make.

The best thing to do is create a benchmark. Then any changes you make in the system can be compared against this benchmark.  You’ll be able to quantify any performance changes with the user community by comparing the results with your known benchmark.  This could be done for a new tools release, a new piece of hardware, network architecture…  Anything.

Our LTAAS (load testing as a service) offering can enable you to do this remotely, any time you like.  We are able to engineer specific tests for your site and execute them when you want in the concurrency that you want.  We are also able to configure all monitoring to ensure that not only the performance data (in terms of response times) is stored, but also the performance metrics from the hardware.  We can save off your results and then compare them if you execute the tests again.  We are also able to compare these results with know industry benchmarks to ensure that your performance profile is within industry standards.

Remember that you can do all of the tuning in the world, but 1 bad query from a user can bring the system to it’s knees!

This is a great toolset that you are able to augment with your own bag of tricks.  Send me an email shannon.moir@myriad-it.com if you’d like to know more.

windoze search is a COMPLETE DONKEY

Tell me this, please…

I do the following in windows explorer search:

image

contents:ORA and I get NO results

I search for ORA and then click file contents and I get no results

image

I then go to my trusty command window and enter:

D:\JDEdwards\E910\log>findstr ORA *.log

and I get a TON of results.

I honestly don’t know how we are supposed to trust an OS (a commercially focused OS like 2008R2) if it cannot search the contents of TXT files / log files “out of the box”.

Do I really need to change the role of the server to enable windows search service to search the contents of log files?

Wednesday, 4 December 2013

JD Edwards performance testing using Oracle Application Testing Suite

I thought that I’d provide some very generic guidelines for performance testing and JD Edwards 9.1.  These figures can be used as a guide for your systems performance.  If course, these tests and scenarios are very limited.

I have a scenario, 1 web server, 1 DB server, 1 app server.  I log into E1, I launch AB, index search 1 record, close AB, open BV, run R0010P, close BV logout close browser.

I create a load test using Oracle Application Test Suite.

I configure all of my counters

I configure 20 concurrent users (to being with)

I choose to have 0 wait time, so I’m perf testing.

I run this scenario for 10 minutes.

What do you think the results might be? 

Name Value Min Max Avg
Transaction/s .827 .082 2.579 2.272
Pages/s 8.8 .667 26.2 22.68

image

 

image

 

So these are very interesting stats.  Each user is getting 1 page per second, Each user is getting 10 hits per second.  Each user is generating 58KB/s.

I find the final item interesting, as this allows you to know exactly how much a very fast moving user is using on average for E1 – this is 0 wait time, so a user could not actually achieve this (none that I know).

Like I said, this is a 1 off very simple sample.

Oracle Application Testing Suite is fantastic and is exceptionally easy to use.  Although, what you do not have (and I do) is the ability to compare values between sites and know where you can make considerable performance improvements!

Wednesday, 27 November 2013

Oracle procedures and calling them from a BSFN

We are doing some pretty edgy stuff at the moment.  We are getting JD Edwards to call oracle procedures via OCI calls in kernels.  This is some nice stuff to have complete commitment control over function and procedure calls from within E1.

We are working on all of the syntax and semantic issues at the moment.

At the end of the day we are going to have a generic BSFN that is going to take 3 parameters:

procedurename

parameters in (pipe delimited)

parameters out (pipe delimited)

Therefore, the BSFN can be nice and generic and send a bunch of parameters to the stored proc, it’ll extract them all with it’s beautiful PL/SQL logic and hand any returns back when it is done – nice!

Note that this will be timed out if there is no response to the BSFN in 60 seconds, which will be no good for interactive apps

create or replace Procedure TESTDTA.ProcTest
(procName IN varchar2, environ IN varchar2, paramList IN varchar2, resultsList OUT varchar2)
AS
  nextID number;
BEGIN
DBMS_OUTPUT.PUT_LINE('In Procedure');
SELECT testdta.ProcedureSeq.nextval INTO NextID FROM DUAL ;
insert into TESTDTA.ProcedureTest values (ProcTest.procName, ProcTest.environ, ProcTest.paramList, CAST(nextID as varchar(20) ) );
END;

Run it with the following:

declare
  ReturnVal  varchar(20);
begin
  TESTDTA.ProcTest('This is procedure name', 'DV910', 'This|Is|999|params', ReturnVal);
  DBMS_OUTPUT.ENABLE(1000000);
  dbms_output.put_line(ReturnVal) ;
END ;

Check that things get inserted. 

select * from testdta.ProcedureTEst;

image

Nice, all is working. Note that the procedure needed to be created in the same schema as the sequence and the table.  If I did not create the procedure in the same owner / schema – it was unable to find the sequence or the table even when I explicitly referenced them.

So, this is perfect.  I have a working procedure in my TESTDTA owner – now I have to code the OCI routines to call the procedure.  There are two ways of doing this:  OCI (nice, neat secure) or system out a call to a vbscript (not nice, neat or secure – but quick).  I’m going with OCI.

OCI is going to be slightly painful, for a number of reasons.  I need to use 32bit OCI libraries and I also need to do “loadlib” calls and function pointers – as the oci libs are not going to be in my lib path when compiling BSFN’s on the server (or the client).  This is somewhat painful.  I’ll get it all working standalone and then build my function pointers into a BSFN.

This might be a longer post than usual, so I’ll do it in parts.