Quantcast
Channel: Shannon's JD Edwards CNC Blog
Viewing all 541 articles
Browse latest View live

AS/400 migration performance comparison

$
0
0

I need to get this down on paper so I do not forget.

Once again, large (2TB+) AS/400 migration to Oracle (ODA).

Doing some batch performance compares – the easy way.

Quick question though, how many SQL statement per second do you think the ODA can run for a batch job – complete SQL statements?

We are seeing up to 3600 per second – and it’s still slower than the 10 year old 400!!!  WTF?

That AS/400 is capable of some amazing feats.

Anyways, back to the blog.

Here is a way you can replicate a batch load, firstly get a snapshot of performance on the as/400 with something like this:


SELECT JCPID as INNERPID, JCVERS as INNERVERS, trim(simd) || '-' || trim(vrjd),
   count(1) as INNERCOUNT,
   Avg(86400*(JCETDTIM-JCSTDTIM)) as INNERAVERAGE,
   min(86400*(JCETDTIM-JCSTDTIM)) AS INNERMIN,
   max(86400*(JCETDTIM-JCSTDTIM)) AS INNERMAX, avg(jcpwprcd) as "ROWS PROCESSED"
from svm900.f986114@purgatorydb t1,ol900.f9860@purgatorydb, copd900.f983051@purgatorydb, svm900.f986110@purgatorydb t2
where trim(t1.jcpid) = trim(siobnm)
and trim(t1.jcvers) = trim (vrvers)
and trim(t1.jcpid) = trim (vrpid)
and t1.jcjobnbr=t2.jcjobnbr
and t1.jcexehost = 'PURGATORY'
group by 'runube JDE JDE PY900 *ALL ' || JCPID || '' || JCVERS ||
CASE  WHEN jcjobque IS NULL THEN N'QBATCH' WHEN jcjobque = '' THEN N'QBATCH' ELSE jcjobque END  || ' Batch Hold Save', t1.jcpid, JCVERS, trim(simd) || '-' || trim(vrjd)
having Avg(86400*(JCETDTIM-JCSTDTIM)) > 15 and Avg(86400*(JCETDTIM-JCSTDTIM)) < 15000;


This is going to give you the batch jobs on the AS/400 that on average tool more than 15 seconds and less than 150000 seconds.

My results give me about 700 jobs.

I can then use the list and save it off in excel as a baseline of performance – because this is going to be handy when comparing with oracle.

image

I can then feed this into a file in Linux and rip it apart to generate a script:

cat *.list | awk '{printf("./runube.ksh %s %s >> %s_%s.out\n",$1,$2,$1,$2)}'> runAWR_new.ksh

which creates something like:

./runube.ksh R03B413A S1501 >> R03B413A_S1501.out
./runube.ksh R03B50 S0001 >> R03B50_S0001.out
./runube.ksh R03B500X F5001 >> R03B500X_F5001.out
./runube.ksh R03B50D F8101 >> R03B50D_F8101.out
./runube.ksh R56202 S1501 >> R56202_S1501.out
./runube.ksh R03B571 F5004 >> R03B571_F5004.out
./runube.ksh R03B571 F5000 >> R03B571_F5000.out
./runube.ksh R42800 S5917 >> R42800_S5917.out
./runube.ksh R42800 S1713 >> R42800_S1713.out
./runube.ksh R42800 S1729 >> R42800_S1729.out
./runube.ksh R42800 S1727 >> R42800_S1727.out
./runube.ksh R047001A S0001 >> R047001A_S0001.out
./runube.ksh R09801E ZJDE0001 >> R09801E_ZJDE0001.out
./runube.ksh R11414A S0028 >> R11414A_S0028.out
./runube.ksh R11414A S0002 >> R11414A_S0002.out
./runube.ksh R30601 S0001 >> R30601_S0001.out
./runube.ksh R30601 S0001 >> R30601_S0001.out
./runube.ksh R42995 S8301 >> R42995_S8301.out

I then have my runube.ksh script that does the following:

$ vi runube.ksh
#!/bin/ksh
if [ $# -lt 2 ]
   then
    echo "USAGE: $0 REPORT VERSION"
    exit
fi
echo "set feedback off"> sql$$.sql
echo "EXEC DBMS_WORKLOAD_REPOSITORY.create_snapshot;">> sql$$.sql
echo "select 'START##' || max(snap_id) from dba_hist_snapshot ;">> sql$$.sql
echo "quit;">> sql$$.sql
STARTSNAP=`sqlplus JDE/PASS@JDEPROD @sql$$.sql |grep \#\# |grep -v \'|grep START|awk -F\# '{print $3}'`
echo $1_$2 RUNNING##
echo "<h1> UBE $1 VERSION $2 </h1>">$1_$2_AWR.html
echo "<h2>">>$1_$2_AWR.html
(time runube JDE PASS PD900 *ALL $1   $2     QBATCH     Interactive Hold Save) 2>&1 | grep m |egrep '^user|^sys|^real'>> $1_$2_AWR.html
echo "</h2>">>$1_$2_AWR.html
ENDSNAP=`sqlplus JDE/PASS@JDEPROD @sql$$.sql |grep \#\# |grep -v \'|grep START|awk -F\# '{print $3}'`
#AWR time  <--  This is a comment – how RAD!
echo "set linesize 8000">sql$$.sql
echo "set feedback off;">>sql$$.sql
echo "set heading off;">>sql$$.sql
echo "set verify off;">>sql$$.sql
echo "SELECT output FROM    TABLE(dbms_workload_repository.awr_report_html ((select dbid from v\$database),(select instance_number from v\$instance),$STARTSNAP,$ENDSNAP,8 ));">> sql$$.sql
echo "quit;">> sql$$.sql
cat sql$$.sql
sqlplus JDE/PASS@JDEPROD @sql$$.sql >> $1_$2_AWR.html
rm -f ./sql$$.sq
#aws s3 cp $1_$2_AWR.html s3://mybucketofawr/$1_$2_AWR.html


RAD hey!!

This has done a lot.  Firstly it’s got a baseline of performance stats from the 400

Created a script that will run all of these jobs (one after the other) there is not parallel to make sure that the AWR’s are good

It generates AWR’s for you for each job

It then will put them into an S3 bucket if you are nerdy like me


Then, when you run them all on your new kit, you can have a spreadsheet like the one below which can compare the performance of the AS/400 and the new kit:


image


The spreadsheet can calculate the URL to get to the AWR in S3, so you can distribute these results and ppl can see the reports and see why things are performing the way that they were.

Note that if you do not want the AWR’s or anything like that, you can have the SQL generate a simple and native runube command:

SELECT 'runube JDE PASSPY900 *ALL ' || JCPID || '' || JCVERS ||
CASE  WHEN jcjobque IS NULL THEN N'QBATCH' WHEN jcjobque = '' THEN N'QBATCH' ELSE jcjobque END  || ' Batch Hold Save',
   t1.JCPID as INNERPID, t1.JCVERS as INNERVERS, simd || vrjd,
   count(1) as INNERCOUNT,
   Avg(86400*(JCETDTIM-JCSTDTIM)) as INNERAVERAGE,
   min(86400*(JCETDTIM-JCSTDTIM)) AS INNERMIN,
   max(86400*(JCETDTIM-JCSTDTIM)) AS INNERMAX
from svm900.f986114@purgatorydb t1,ol900.f9860@purgatorydb, copd900.f983051@purgatorydb, svm900.f986110@purgatorydb t2
where trim(t1.jcpid) = trim(siobnm)
and trim(t1.jcvers) = trim (vrvers)
and trim(t1.jcpid) = trim (vrpid)
and t1.jcjobnbr=t2.jcjobnbr
and t1.jcexehost = 'PURGATORY'
group by 'runube JDE JDE PY900 *ALL ' || JCPID || '' || JCVERS ||
CASE  WHEN jcjobque IS NULL THEN N'QBATCH' WHEN jcjobque = '' THEN N'QBATCH' ELSE jcjobque END  || ' Batch Hold Save', t1.jcpid, JCVERS, simd || vrjd
having Avg(86400*(JCETDTIM-JCSTDTIM)) > 15 and Avg(86400*(JCETDTIM-JCSTDTIM)) < 15000;




Refresh your orchestrations for testing... Enable Admin Service.

$
0
0
Want to do some orchestration development and tired of making changes in the orchestration studio and not being able to test them in the orchestration client, wow - I know that this got to me after about 3 minutes of development.

All you need to do is enabled the "Enable Admin Service" option for the AIS server that you are pointing to, this is done from server manager under the general tab.  See below for the screen grab.  You need to make sure that the option is ticked, then bounce the AIS server.









Now when you click the XML cache refresh from the orchestration client, you'll get the edition of your orchestration that you just saved, not one from an hour ago!


When it's done right, you'll get the following confirmation




Not the permission error that you previously got.

very basic post, OEL RHEL change TZ for proper date and time stamps

$
0
0
The little things get to me when I'm troubleshooting, like date and time. 

If I look at the machine and NTP is set up properly but my timestamps are wrong, then generally this is going to be related to TZ. Very simple steps to getting this right for Melbourne: 

 To validate that this is your problem, you can enter the command below: 

It gives you some really cool information about daylight savings and NTP - which you need to know.

[root@ip-10-10-1-235 ~]# timedatectl
      Local time: Tue 2018-04-03 23:24:28 UTC
  Universal time: Tue 2018-04-03 23:24:28 UTC
        RTC time: Tue 2018-04-03 23:24:28
       Time zone: n/a (UTC, +0000)
     NTP enabled: yes
NTP synchronized: yes
 RTC in local TZ: no
      DST active: n/a

Okay, this needs to be fixed!  See how there is no information about DST or TZ

One simple command as root

ln -sf /usr/share/zoneinfo/Australia/Melbourne /etc/localtime

Then viola!

[root@ip-10-10-1-235 ~]# timedatectl
      Local time: Wed 2018-04-04 09:21:07 AEST
  Universal time: Tue 2018-04-03 23:21:07 UTC
        RTC time: Tue 2018-04-03 23:21:06
       Time zone: Australia/Melbourne (AEST, +1000)
     NTP enabled: yes
NTP synchronized: yes
 RTC in local TZ: no
      DST active: no
 Last DST change: DST ended at
                  Sun 2018-04-01 02:59:59 AEDT
                  Sun 2018-04-01 02:00:00 AEST
 Next DST change: DST begins (the clock jumps one hour forward) at
                  Sun 2018-10-07 01:59:59 AEST
                  Sun 2018-10-07 03:00:00 AEDT

Cool, and yes - DST did change on Sunday.  Nice reminder. 

 You can work out your own settings from this example.

One bad orchestration can ruin the entire testing platform

$
0
0

This problem took too long to solve, but let me tell you about it – as it might save you some time.  I’ve been creating orchestrations of various complexity and am enjoying the tasks.  There are a number of things that I’d like to see improved -

  • math_numeric handling of return values-  not everything is a string.  There needs to be some native casting capabilities.  This occurs when you create a new AN8 (for example) and then want to pass that into the P0092 form as the users AN8.  It’s passed back as a string and the orchestration does not work.  You also cannot change this.  Frustrating to need to use data service to get a number back.

image

  • You do not see return values until you save or change something in the orchestration studio

image

  • Complex logic is not going to happen in the standard development environment, you will need to write some java

image

That’s just my list at the moment, let’s settle back for the current problem though.

I just created a new custom orchestration which added a work order, nice – I’ve done this a number of times before.  Very simple form request and then an orchestration over the top.  But, something went wrong.

When I went to test it (or ANY orchestration, I did not get any parameters in the list).

It looked like the following

<Orchestration>
   <shortDesc>Add a WO for a thing that you get out of the cross reference</shortDesc>
   <inputFormat>JDE Standard</inputFormat>
   <version>v2</version>
   <inputTypes>
     <inputTypes type="String" required="false">
       <name>orch_inputszUnitNumber</name>
       <defaultValue>FR007</defaultValue>
     </inputTypes>
     <inputTypes type="String" required="false">
       <name>orch_inputszFailureDescription</name>
     </inputTypes>
   </inputTypes>
   <productCode>55</productCode>
   <orchestrationSteps>
     <orchestrationSteps type="ServiceRequest" omwObjectName="SRE_1804030006CUST">
       <name>20180403_AddWO</name>
       <outputMappings><formOutputMappings>
           <formOutputMappings>
             <formIndex>4</formIndex>
             <outputMappings>
               <outputMappings>
                 <name>235</name>
                 <id>235</id>
               </outputMappings>
             </outputMappings>
           </formOutputMappings>
         </formOutputMappings>
       </outputMappings>
       <transformations>
         <transformations input="orch_inputszUnitNumber" output="inStringUnitNumber"/>
         <transformations input="orch_inputszFailureDescription" output="szFailureDescription"/>
       </transformations>
     </orchestrationSteps>
   </orchestrationSteps>
</Orchestration>

If you were to try and import this into your orchestration studio, you might find the same problem:

image

See that all of my parameters are missing!

But, if I delete the orchestration (now that I know the one).

using P98220U

image

Yes!

It immediately starts working again

image

Very strange.

to solve this I did spend hours debugging logs, installing new tools releases, restarting everything…  deleting UDO’s and more.

If you do not see parameters in the orchestration client, take a look at the last orchestration that you created!

9.2.2.4 JD Edwards has been released

$
0
0

There are some exciting enhancements in this release, please look at https://docs.oracle.com/cd/E53430_01/EOTNC/software_updates.htm#EOTNC223 for some more information.

I'll be demonstrating the orchestration changes in a series over the next week.

In particular - look for :
launching BV's and changing data selection and processing options:
https://docs.oracle.com/cd/E53430_01/EOTOT/config_orchestration.htm#EOTOT555

a new report type service request.


imageGreat if you want to change data selection or POs for the launch


image

output overrides can be specified too


In Server Manager, you can enable error and exception handling for orchestrations. When enabled, each exception in an orchestration is saved as a single serialized JSON object and stored in a directory on the AIS Server. In addition to storing these files, the directory serves as a buffer for storing orchestration requests if the EnterpriseOne system is down.


When creating orchestrations, business analysts can include an array as an orchestration input, defining the set of data to pass within the array. You can use an array in two ways: with the orchestration ”Iterate Over” feature to repeatedly call a service request for each row in the array; or add to or update a grid by referencing the array name inside the service request at the grid level.


image


New FTP connector has been added

JDE920 and JDE910 batch job performance summary for AS/400 SQL

$
0
0


The following SQL will give you a summary of all batch jobs and how long they’ve taken to run (in seconds) on average on an AS/400 – note that this is specific syntax for the 400.  The date arithmetic is also quite specific for the AS/400.

SELECT JCPID as INNERPID, JCVERS as INNERVERS, TRIM(JCPID)||TRIM(JCVERS), simd || vrjd,
   count(1) as INNERCOUNT,
   Avg((DAYS(jcetdtim) - DAYS(jcstdtim)) * 86400 + (MIDNIGHT_SECONDS(jcetdtim) - MIDNIGHT_SECONDS(jcstdtim))) as INNERAVERAGE,
   min((DAYS(jcetdtim) - DAYS(jcstdtim)) * 86400 + (MIDNIGHT_SECONDS(jcetdtim) - MIDNIGHT_SECONDS(jcstdtim))) AS INNERMIN,
   max((DAYS(jcetdtim) - DAYS(jcstdtim)) * 86400 + (MIDNIGHT_SECONDS(jcetdtim) - MIDNIGHT_SECONDS(jcstdtim))) AS INNERMAX, avg(jcpwprcd) as "ROWS PROCESSED"
from svm910.f986114 t1,ol910.f9860, copd910.f983051, svm910.f986110 t2
where trim(t1.jcpid) = trim(siobnm)
and trim(t1.jcvers) = trim (vrvers)
and trim(t1.jcpid) = trim (vrpid)
and t1.jcjobnbr=t2.jcjobnbr
and t1.jcexehost = 'SYDJDE01'
group by  t1.jcpid, JCVERS, simd || vrjd ;

to reveal

image

Like my data obfuscation?

So you can quickly see long running jobs or compare averages.

The things that I want to remember out of this is the AS/400 syntax.

12.2.2.4 is released, so let’s upgrade WLS to 12.2.1.3–or NOT

$
0
0

MTR’s say that we are good to go:

image

Nice to put on the latest, but…

Then I find:

https://docs.oracle.com/middleware/12213/wls/WLUPG/intro.htm#WLUPG107

and…

Note:

As of WebLogic Server 12.1.2, Oracle no longer provides upgrade installers. You must install WebLogic Server 12.2.1.3.0 to a new directory location. You cannot install it over an existing installation.

Doh!  I thought that there might be a nice little (or big) opatch that I could apply – but it seems that things are a little more difficult than that.

I’m trying to solve an issue with 9.2.2.4 and WLS 12.2.1.2 on OEL that is not allowing me to login to JDE, getting stuck threads on the login page:


####<Apr 17, 2018, 1:11:22,535 PM AEST> <Error> <WebLogicServer> <ip-10-10-1-235.ap-southeast-2.compute.internal> <IOT_AISWEB_9201> <[ACTIVE] ExecuteThread: '4' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <00c06b7e-0c5a-4892-b8bb-79a54660fc84-0000001e> <1523934682535> <[severity-value: 8] [rid: 0] [partition-id: 0] [partition-name: DOMAIN] > <BEA-000337> <[STUCK] ExecuteThread: '8' for queue: 'weblogic.kernel.Default (self-tuning)' has been busy for "708" seconds working on the request "Http Request Information: weblogic.servlet.internal.ServletRequestImpl@5d9d6b3e[POST /jde/E1Menu.maf]
", which is more than the configured time (StuckThreadMaxTime) of "600" seconds in "server-failure-trigger". Stack trace:
         sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
         sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
         sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
         sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
         sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
         weblogic.socket.NIOInputStream.readInternal(NIOInputStream.java:146)
         weblogic.socket.NIOInputStream.read(NIOInputStream.java:90)
         weblogic.socket.NIOInputStream.read(NIOInputStream.java:73)
         weblogic.socket.JSSEFilterImpl.readFromNetwork(JSSEFilterImpl.java:496)
         weblogic.socket.JSSEFilterImpl.handleUnwrapResults(JSSEFilterImpl.java:675)
         weblogic.socket.JSSEFilterImpl.unwrapAndHandleResults(JSSEFilterImpl.java:554)
         weblogic.socket.JSSEFilterImpl.doHandshake(JSSEFilterImpl.java:99)
         weblogic.socket.JSSEFilterImpl.doHandshake(JSSEFilterImpl.java:78)


Yet when I install this on 12.2.1.1 – all works fine.

I’ve applied a bunch of patches to try and get it working (including 26860993), oh after removing others

/Oracle_Home/OPatch/opatch rollback -id 26485996

/Oracle_Home/OPatch/opatch rollback -id 24521759

but still no logging into JDE – stuck during login.

So, I may try more patching or a new instance at 12.2.1.3 and see if I can login to JAS

Let me know if you have the same issue.

Install WLS 12.2.1.3 on Linux

$
0
0

get a xterm or vnc session to the machine

image

y

image

next next next..

image

takes about 1 minute

image

Take note of where the logs are for later

Ensure that you launch the config assistant

image

and rename it to what you want – this might be helpful in SM

Note that I like e1apps and then release

image

Next

image

I keep username default

dev mode, because I love boot.properties

image

choose all 3 because you need a machine

image

I’m already using 7001 and 2 so..

image

Node manager per domain

image

Leave clusters, but add a machine

image

Assign servers to machine

image

3 seconds later, done

image


/app/wls_12.2.1.3/user_projects/domains/e1apps_12.2.1.3/startWebLogic.sh


image

job done

image

register with SM

image

Then choose 12c

image

Then enter the details of your install

image

don’t use any ‘.’s in the name

image

create instance!

image

interestingly I’m getting this in the console logs

image

Looks like the weblogic password is not being saved in SM properly

click on your domain name in SM, then add a server

image

Note that this password problem seems to the the cause of all my issues at the moment, as SM cannot talk to the admin server because the password is not saving.

This problem was silly me!!  The username was saved in the console as “weblogic “ there was a space at the end of the username, therefore when I saved the password it’d error out each time with a red error.  Eventually the system would lock out WLS.

I had to have the username as weblogic no space and use the save button (as below)

image

And then restart AdminServer at the command line, then save the password in SM – and it finally took!

I was then able to create my additional server easily

image

And now install JAS 9.2.2.4 to it

image

Note that I have a 9201 running, so I’m going to take that down to avoid locking.

image

Create

image

it seems that you can create without a node manager.

But you cannot start or synchronize the content without a nodeManager

Now my JDE works, I do not get the stuck thread issues that I was with 12.2.1.2


Using orchestration recorder (Service Request Recorder) in tools 9.2.2.4

$
0
0

make sure that you have the UDC’s correct
Access the Feature Security application thru P00950 and add the following UDC values:

H95|UF

KY = RECORDER DL01 = Process Recorder SPHD = 1 HRDC = N

H95|UO

KY = RECORDER DL01 = Process Recorder SPHD = 1000 HRDC = N

Then proceed to activate the feature to be used in EnterpriseOne applications.

Here is a video to assist – my first vlog!


JD Edwards Orchestration using iterate over for orchestration input

$
0
0

I must admit, I found this one a little frustrating, but good to get it out of the way.

This is solving the problem of the parent / child orchestration (parent child being defined within the input document).

I created a very simple orchestration:

image

Basically iterate over my array of ColourList (sorry USA, this is how well spell it down under), for each of the elements in the colour list, send me an email.

My array is currently true to the word, an array – but it’s not an array of structures yet.

image

A single dimension Array with Colour as the only element.

Therefore, my orchestration should take the input and send me an email with the title of the colour – nice and easy…  For every colour that I list.

But, the real question is – how do I form the input JSON for this function? 

This is going to save quite a bit of heart ache

{
   "inputs" : [ {
     "name" : "SingleInputString",
     "value" : "Hello"
   }],
   "detailInputs": [{
    "name": "ColourList",
    "repeatingInputs": [
      {
        "inputs": [
          {"name":"Colour","value":"Pink" }
        ]
      },
      {
        "inputs": [
          {"name":"Colour" ,"value": "Red" }
         ]
      }
   ] }
   ]
}

There is a lot of verbage here and a lot of terms that need to be in the JSON, otherwise it will not iterate, trust me.  I tried many combinations.

You need to ensure that you use the object “repeatingInputs” – casE sensitive.  You need to also include inputs array

To Get 4 emails, I post the following JSON

{
   "inputs" : [ {
     "name" : "SingleInputString",
     "value" : "Hello"
   } ],
   "detailInputs" : [ {
     "name" : "ColourList",
     "repeatingInputs" : [ {
       "inputs" : [ {
         "name" : "Colour",
         "value" : "Pink"
       } ]
     }, {
       "inputs" : [ {
         "name" : "Colour",
         "value" : "Red"
       } ]
     }, {
       "inputs" : [ {
         "name" : "Colour",
         "value" : "Blue"
       } ]
     }, {
       "inputs" : [ {
         "name" : "Colour",
         "value" : "Turquoise"
       } ]
     } ]
   } ]
}

Nice!

image


I’ve been using an online JSON editor, because the orchestration client (bless it) does not help my crappy syntax.  This is great!

image

You know that you’ve made a mistake in JDE, if you hit for format button and it bombs – your JSON is bad

image

If it’s good, it’ll look nicely formatted, but this does not mean that the document is formed correctly.  You could not be using key value pairs, and it’ll still format, just nothing will work on the AIS server!

All you need to do is follow my basic template above and all will work.  Here is a copy of my orchestration too – just in case you want to test the document yourself.

Note that the service request is hard coded to send an email to me, so you might want to change that.

You can grab my code here: https://drive.google.com/file/d/10KBi7XNuqnSIYwzgb921lTqvDj0SKTYw/view?usp=sharing

Service discovery and tools release 9.2.2.4

$
0
0

Okay, service discovery is cool and easy and might help your describe your services to someone.

Problem is that this could be much better with something like swagger – but you gotta start somewhere – hey!

you need to do a get from your AIS server with batch authentication

https://f5iot.mye1.com/jderest/discover

That is with a header something like:

Authorization: Basic U0hBTk5PTk06YWJjMTIz

Note that this was generated with a temp password, so nothing decent in that.

note that this is just username : password in base64

So, all you need to do it goto http://decodebase64.com/

type in my auth token above and see

image

Too easy, it’s already changed.

Here is a video showing what you can do

Note that a nice thing is getting the array syntax that I described the other day

    "name" : "20180424_CallSendMessage",     "omwObjectName" : "ORC_1804240002CUST",     "udoGroup" : "Personal",     "description" : "Confirm it",     "inputFormat" : "JDE Standard",     "version" : "v2",     "inputs" : [ {       "name" : "SingleInputString",       "type" : "String"     }, {       "name" : "ColourList",       "type" : "Array",       "array" : [ {         "name" : "Colour",         "type" : "String"       } ]     } ],

change IP address of weblogic server… don’t forget the adminserver cache

$
0
0

There are a heap of instructions of what you need to change if you change the IP address of your weblogic server, but I find they are not complete.  Google it and use oracle support.  The classic sections are:


For the Administration Server and Managed Servers:

For Node Manager:

  • Modify the IP Address in the WebLogic Server Administration Console, in Home >Summary of Machines > Configuration > Node Manager;
  • Modify occurrences of the IP Address in the nodemanager.properties


It’s easy to grep around for the ADMIN_HOST through the start scripts and the nodemanager.properties files, but this will not fix things.  For example, look at this ps output.

Classic example:  You can see that the management.server is listed as http://10.250.252.190:7001 , yet the ip address of the server is a new and improved 10.255.252.201

[root@northstar ~]# ps -ef |grep java |grep 9085
oracle    2162  2105  0 12:47 ?        00:01:09 /usr/java/jdk1.7.0_99/bin/java -server -Xms256m -Xmx512m -XX:MaxPermSize=256m -Dweblogic.Name=NORTHSTAR_HTML_9085 -Djava.security.policy=/u01/Oracle_Home/wlserver/server/lib/weblogic.policy -Dweblogic.ProductionModeEnabled=true -Dweblogic.system.BootIdentityFile=/u01/Oracle_Home/user_projects/domains/e1apps/servers/NORTHSTAR_HTML_9085/data/nodemanager/boot.properties -Dweblogic.nodemanager.ServiceEnabled=true -Dweblogic.nmservice.RotationEnabled=true -Dweblogic.security.SSL.ignoreHostnameVerification=false -Dweblogic.ReverseDNSAllowed=false -XX:MaxPermSize=256m -Dweblogic.wsee.wstx.wsat.deployed=false -Xms2048m -Xmx2048m -Dweblogic.security.SSL.ProtocolVersion=TLSv1.2 -Duser.timezone=Pacific/Auckland -Djava.endorsed.dirs=/usr/java/jdk1.7.0_99/jre/lib/endorsed:/u01/Oracle_Home/wlserver/../oracle_common/modules/endorsed -da -Dwls.home=/u01/Oracle_Home/wlserver/server -Dweblogic.home=/u01/Oracle_Home/wlserver/server -Dweblogic.management.server=
http://10.250.252.190:7001 -Dweblogic.utils.cmm.lowertier.ServiceDisabled=true weblogic.Server

[root@northstar ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
         inet 10.255.252.201  netmask 255.255.255.0  broadcast 10.255.252.255
         inet6 fe80::216:3eff:fe1a:15c3  prefixlen 64  scopeid 0x20<link>
         ether 00:16:3e:1a:15:c3  txqueuelen 1000  (Ethernet)
         RX packets 142041  bytes 12104966 (11.5 MiB)
         RX errors 0  dropped 0  overruns 0  frame 0
         TX packets 38313  bytes 8723699 (8.3 MiB)
         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

When I start this server with commandline on Linux, it starts, but does not register with SM and cannot login with a connection error.

[root@northstar default]# pwd
/u01/Oracle_Home/user_projects/domains/e1apps/servers/AdminServer/data/store/default

-rw-r-----. 1 oracle oracle 1049088 Apr 30 12:49 _WLS_ADMINSERVER000000.DAT

The file above in the DIR above, as the incorrect server address in it’s config:


[root@northstar default]# grep 10. _WLS_ADMINSERVER000000.DAT
Binary file _WLS_ADMINSERVER000000.DAT matches

It’s a binary match – this needs to be removed.

stop admin server:

delete it

goto

/u01/Oracle_Home/user_projects/domains/e1apps/servers/AdminServer/data/nodemanager
[oracle@northstar nodemanager]$ ls -l
total 16
-rw-r-----. 1 oracle oracle  13 Apr 30 21:15 AdminServer.state
-rw-r-----. 1 oracle oracle  27 Apr 30 12:47 AdminServer.url
-rw-r-----. 1 oracle oracle 174 Sep 22  2017 boot.properties
-rw-r-----. 1 oracle oracle 432 Sep 22  2017 startup.properties

change AdminServer.url

NOW:

startManagedWebLogic.sh

ps –ef |grep java

you’ll see that your process now has the correct management server defined (FQDN for the machine – YAY!)


oracle    3709  3653 53 21:22 pts/0    00:00:24 /usr/java/jdk1.7.0_99/bin/java -server -Xms256m -Xmx512m -XX:MaxPermSize=256m -Dweblogic.Name=NORTHSTAR_HTML_9085 -Djava.security.policy=/u01/Oracle_Home/wlserver/server/lib/weblogic.policy -Dweblogic.ProductionModeEnabled=true -Dweblogic.security.SSL.trustedCAKeyStore=/u01/Oracle_Home/wlserver/server/lib/cacerts -Djava.endorsed.dirs=/usr/java/jdk1.7.0_99/jre/lib/endorsed:/u01/Oracle_Home/wlserver/../oracle_common/modules/endorsed -da -Dwls.home=/u01/Oracle_Home/wlserver/server -Dweblogic.home=/u01/Oracle_Home/wlserver/server -Dweblogic.management.server=http://northstar.xxx:7001 -Dweblogic.utils.cmm.lowertier.ServiceDisabled=true weblogic.Server
oracle    3829  2836  0 21:23 pts/0    00:00:00 grep --color=auto java
[oracle@northstar default]$


Following my instructions – you’ll delete the DAT file and change the ADminServer.url file and start the AdminServer again – you’ll find everything works.

Instead of

image

I get

image




using swagger hub to document your orchestrations

$
0
0
I recently did a post on how you can use orchestration discovery, which is a nice way to get orchestration definitions from JDE.

Recently swaggerhub released the ability to create swagger definition - well at least a template from a REST call.  So, of course I decided to see what it would do with an orchestration.

https://inspector.swagger.io/builder/builder is the site you can use to call your orchestration and get a nice swagger definition of the API.

Of course, nothing is free.If you want to export this definition to swagger, you need to make it public or your need to pay for a subscription.  I decided to risk it, but it also seems that swagger leaves the entire request (including username and password) in the template - so you might want to get in there a remove it.

The other problem I found with swaggerhub (GDPR does not exist there?) is that I cannot seem to delete the definition.

I end up with:

swagger: '2.0'info:  description: defaultDescription  version: '0.1'  title: defaultTitlepaths:  /orchestrator/20180327_AddAddressBook:    post:      consumes:        - application/json      produces:        - text/html      parameters:        - in: body          name: body          required: false          schema:            $ref: '#/definitions/Model0'          x-examples:            application/json: |-              {                  "username":"SHANNONM",                  "password":"",                "inputs" : [ {                  "name" : "inputAddressDescription",                  "value" : "Shannon Moire"                }, {                  "name" : "inputAddressType",                  "value" : "E"                }, {                  "name" : "inputLongAddressNumber",                  "value" : "45674564551"                } ]              }      responses:        '200':          description: Definition generated from Swagger Inspectordefinitions:  Model0:    properties:      username:        type: string      password:        type: string      inputs:        type: array        items:          $ref: '#/definitions/Inputs'  Inputs:    properties:      name:        type: string      value:        type: string

As my definition.


It's not perfect, as the key:value pairs for the parameters mean something in JDE, so there might be some massage required - but a great start to creating swagger defs for orchestrations!

If you want to take a look at my definition, you can do so here:

We can all hope for a better described and easier way of enterprise real time integration!

Reduce your technical debt–embrace User Defined Objects

$
0
0

I’ve done a number of posts on this topic, but we all should be looking toward configuration not code to personalise our JD Edwards environment.  Training for end users and developers must be on the new UDO’s that allow us to modify and personalise our environments based upon config.

For instance, Personalize forms allow you to:

  • Modify field labels
  • Hide, resize, and reposition fields and controls
  • Grid guidelines to help with alignment when moving field (TR 9.2.1.2 and up)
  • Ability to move controls using arrow keys for further refining the alignment (TR 9.2.1.2 and up)
  • Ability to rename tab pages and group boxes (TR 9.2.1.2 and up)
  • Ability to edit the tab sequence (TR 9.2.1.2 and up)
  • Cut and paste controls from one tab page to another (TR9.2.1.2 and up)
  • Ability to mark a field as required (TR9.2.1.2 and up)
  • Personalization of Menu Exits (TR 9.2.2.4 and up)
  • Use the personalize exits link to personalize the Form, Row and Report exits (TR 9.2.2.4 and up)

That is a shed load of functionality and would allow you to retire modifications.

The new form extensions, which allow your to do the following changes

  1. Adding Business view Columns to the header or the grid of a form.
  2. Remove Business view Columns from a header of grid of a form.
  3. Resize Form Header and Grid Areas
  4. Resize Business view columns
  5. Repositioning Business View Columns
  6. Setting filter criteria

Each one of these UDO’s (and security) can be used to lower your technical debt and bring you closer to Continuous Delivery for your users.

CodesDescription 01
CAFE1Composite App Framework
COMPOSITEComposite Page
DATABROWSEData Browser
E1PAGEEnterpriseOne Pages
FORMATGrid Format
FORMEXTNSForm Extensions
IMAGEImage
NTFNotification
ONEVIEWOne View Reports
ORCHOrchestrations
PERSFORMPersonal Forms
QUERYQuery
RECORDERProcess Recorder
RULERule
SCHEDULESchedule
SEARCHEnterpriseOne Search
SREQService Requests
TASKSEARCHTask Search
WATCHLISTOne View Watchlist
WLSTWhitelist
XREFCross Reference

My recommendations to you is to understand all of these UDO’s intimately so that if you are retrofitting or thinking about modifications – you can implement them much more efficiently and allow the business to consume change at a great pace.

9.2, OSA and output management

$
0
0

OSA’s do work in 9.2, but you need to activate filesystem output.

You need to activate your report in P98617 to ensure that filesystem output is enabled

clip_image002

So then you can add individual entries

image

Once you have done this, all of the standard OSA functionality is going to work!  YAY!


I did try and leave the PDF / CSV in the database, but the only function I could find to crab it was not exported to the server:

  JDEGetPDFFile(hUser,
             pOSAReportInfo->szHostName,
             pOSAReportInfo->ulJobNum,
             (BYTE *)szLocalFileName,
             &eRetCode);

So, don’t bother trying that.  It’s exported to the client jdekrnl.lib – but not the server.

This might seem cryptic to most people, but if you’ve programmed OSA’s before (they are SOOOO RAD!!!), then this is good info.

Remember that an OSA can be triggered after a UBE and can do things with the output – perfect for emailing and printing automatically.  I have one that turns on logging, that is cool too!


What good performance looks like–Good to Great

$
0
0


Lots of clients at the moment are getting rid of their proprietary CPU architecture.  This comes in the form of RISC type implementations and moving to commodity x86 architecture.  There are a lot of advantages in this, but the primary seems to be the strategic of enabling an easier cloud migration when the time is right. 

I’m assisting with a number of very large platform migrations at the moment – moving from AS/400 to cloud or commodity.  Generally if people are moving off a 400 today, they have been on that platform for a long time..  As I doubt that ANYONE would buy JDE at the moment and get an AS/400 to run it on.  In fact, I doubt that has occurred in the last 8 years (am I wrong – tell me).

So, we are generally migrating 10-20 years of history and customisation to another platform.  It’s rarely JDE that is the problem in this type of migration, it’s all of the stuff that sits on the side of JDE.  The integrations, CL, RPG and custom SQL statements and triggers that make a migration tricky.

There is one more thing that makes this tricky – PERFORMANCE!  Never underestimate the amazing ability that an AS/400 has to process inefficient code well!  It is awesome at masking bad code by monstoring the job with great I/O, reactive (and somewhat invisible tuning) and very quick CPUs.

I quite often need to spend a lot of time tuning the workload (especially custom code) to get the new platforms to behave like the old – and to be honest, sometimes it will not happen…  A massive tablescan based UBE might just take longer on two-tier architecture and single tier AS/400 – but it’s the exception not the rule.

In general large SQL will run faster on new hardware – but it’s the transfer and processing of large datasets that can be problematic.

Look at the graph below.  This shows a client that has recently done a platform migration to Oracle database appliance (X7HA).  This is really smashing the workload, processing Trillions of I/O’s in the first week – yes Trillions!!! 

You can see a pretty cool and consistent graph below of page load times in JDE vs. activity.  The fusion5 ERP analytics suite allows insights like this.  We can see that the interactive performance actually improves when the site gets loaded up.  Makes sense to me.  Better cache is loaded and the users get a better experience.  What does interest me is that 10am when the users are at their most, we have page response time of about .45 seconds – which is amazing (I know, I have over 40 clients to compare with).

It’s really cool to be able to give clients these REAL insights into performance of their new platform and give them unequivocal empirical evidence that they’ve done the right thing and that their users are getting an exceptional interactive experience from the new hardware.

image


We are also able to drill down into some very detailed numbers on where performance problems might be – slowest screens, apps, regions, servers or users.

image

Configuring JMSToolBox to read messages from JDE RTE / Transaction server (weblogic)

$
0
0

Want to look at web logic JMS queue contents?  Want to add some more messages or taketh them away?  This is the post for you.

1. Download JMStoolbox

Check out this https://github.com/jmstoolbox

choose latest release https://github.com/jmstoolbox/jmstoolbox/releases/tag/v4.9.0

clip_image002

Grab the windoze build for 64 bit, it includes java (don’t tell oracle)

2. Unpack, dir should look like:

clip_image004

Grab a copy of wlthin3client.jar from the weblogic server, as seen below: It’s in a a dir something like %ORACLE_HOME%\wlserver\server\lib

clip_image006

Copy it into the lib dir for the JMSToolBox program:

clip_image008

Now, start JMSToolBox

Goto Q Managers and add Oracle WebLogic Server config

clip_image010

Right click weblogic and choose configure

clip_image012

Add the wlthin3client.jar

Great!

Back to sessions

clip_image014

Choose add

Create configuration as this screen

clip_image016

Note that is you are JDE, more likely you do not need t3s, but I was testing. Note also that is the value of the default trust password, nice!

clip_image018

Now when you connect to your server / port combination, you’ll see the messages from JDE into your transaction server.

You then have a bunch of cool options to work with the messages

clip_image020

Creating aggregate data requests using JDE orchestrator

$
0
0

Aggregate data requests can be a little fiddly, but here we go. I find that the best way to test these is to have a simple orchestration, a simple data request and use the orchestrator client to keep running the queries until you get it right.

I’ve very confident to say that if we are updating a data request service request, I know that as soon as you save in the orchestration studio, you can run that change immediately in orchestration client.

I’m going to show 3 scenarios with 3 different outputs.

Scenario 1

Simple single return of a users total value of PO’s that need approval: No aggregation.

clip_image002

This when tested:

Will return all orders and amounts, ordered by amount desc for the user# that I pass in.

clip_image004

As you can see from the above, I have my summary. Note that this is a record set, but not and aggregation.

Scenario 2:

This is slightly more complex, as I’m using aggregation in the query. You can see that I’m including the “generic count”

clip_image006

And the sum of the amount

clip_image008

clip_image010

This results in

clip_image012

Note that this is a single row response because I’m using “assigned to” in the where clause. This is using aggregation and also using sum. A nice query – notice how there is no record set because of the where clause being a single response. This is ALSO the case because I’ve selected:

clip_image014

This is very important. If you include count as above, you must formulate your query to only respond with a single row back – trick for beginners.

Scenario 3:

This is the grizzly bear. I want a result set, which summarises all people who have outstanding PO’s. I want to know the value and the count of the outstanding PO’s too. I want to only see those with a value greater than 0.

clip_image016

The above screen shows all of these elements (do not include count)

clip_image018

This will prevent it from working.

The elements of this are that there is a where clause, as I do not really want one – but am forced, I’ll say where AN8 > 1! I want the sum and count of orders grouped by the person responsible. I also order by order amount desc. I could order by the count of distinct orders too.

Everything else will work as designed, here is the return

clip_image020

Problem:

Aggregation with group by is not a return set.

clip_image022

Note that I want to send an email for each result in the returnset, but I think when you use aggregates, there is only a single return set… Doh!

advanced orchestration lessons

$
0
0

I’ve had a little help on this one, but I wanted to explain some frustrations / limitations in the current edition of the orchestration studio.

My requirements were simple (I thought).

I wanted to scroll through a complex result set, for each row build a string and eventually send that string to a web service.

My web service took a single payload of a parent | child data sequence.

Simple – yeah?  NO!!

image

My initial thoughts were to create the data request and then a groovy connector to concatenate the strings, but this does not work – as the variables only have scope for each iteration of the result set – i.e. I cannot concatenate and get the results after the entire resultset is complete… arrgghh

I started to get fancy and thought that I could use a connector, but this did not work either.

I started creating edit lines, and begin docs – thinking that I was clever, but this did not work either because of the above variable scope and iteration.

So.

I phoned a friend and Trev gave me a tip of manipulating the output of an orchestration.

I then proceeded to have something like:

image


This is simple.

I recommend that if you are going to use this method, you need to get the output of the data request from your orchestration client before you write code, as you will need to understand the output JSON document format.

image

See that I’ve not done and Add’s to the data, left is standard.

Looks something like:

{
   "ServiceRequest1" : {
     "ds_V4209C" : {
       "output" : [ {
         "groupBy" : {
           "F4209.RPER" : 58026
         },
         "F4301.OTOT_SUM" : 756389.52,
         "F4209.DOCO_COUNT_DISTINCT" : 9
       }, {
         "groupBy" : {
           "F4209.RPER" : 8444
         },
         "F4301.OTOT_SUM" : 228918.32,
         "F4209.DOCO_COUNT_DISTINCT" : 9
       }, {
         "groupBy" : {
           "F4209.RPER" : 58018
         },
         "F4301.OTOT_SUM" : 216092.0,
         "F4209.DOCO_COUNT_DISTINCT" : 7
       }, {
         "groupBy" : {
           "F4209.RPER" : 123238
         },
         "F4301.OTOT_SUM" : 113000.0,
         "F4209.DOCO_COUNT_DISTINCT" : 1
       }, {
         "groupBy" : {
           "F4209.RPER" : 7500
         },
         "F4301.OTOT_SUM" : 24893.75,
         "F4209.DOCO_COUNT_DISTINCT" : 3
       }, {
         "groupBy" : {
           "F4209.RPER" : 6002
         },
         "F4301.OTOT_SUM" : 20000.0,
         "F4209.DOCO_COUNT_DISTINCT" : 1
       }, {
         "groupBy" : {
           "F4209.RPER" : 6001
         },
         "F4301.OTOT_SUM" : 2287.29,
         "F4209.DOCO_COUNT_DISTINCT" : 2
       }, {
         "groupBy" : {
           "F4209.RPER" : 533095
         },
         "F4301.OTOT_SUM" : 1327.5,
         "F4209.DOCO_COUNT_DISTINCT" : 7
       }, {
         "groupBy" : {
           "F4209.RPER" : 7504
         },
         "F4301.OTOT_SUM" : 1000.0,
         "F4209.DOCO_COUNT_DISTINCT" : 1
       }, {
         "groupBy" : {
           "F4209.RPER" : 43393
         },
         "F4301.OTOT_SUM" : 593.75,
         "F4209.DOCO_COUNT_DISTINCT" : 1
       }, {
         "groupBy" : {
           "F4209.RPER" : 533093
         },
         "F4301.OTOT_SUM" : 70.0,
         "F4209.DOCO_COUNT_DISTINCT" : 3
       }, {
         "groupBy" : {
           "F4209.RPER" : 70012
         },
         "F4301.OTOT_SUM" : 25.0,
         "F4209.DOCO_COUNT_DISTINCT" : 1
       } ]
     }
   }

With this, I can formulate the code below.  Note the hierarchy of the output and the use of the iterator.


import groovy.json.JsonSlurper;
import groovy.json.JsonBuilder;
import com.oracle.e1.common.OrchestrationAttributes;
String main(OrchestrationAttributes orchAttr, String input)
{
   def jsonIn = new JsonSlurper().parseText(input);
   // modify jsonIn
    
   String bigString = "";
   orchAttr.writeWarn("TEsting");
   items = jsonIn.ServiceRequest1.ds_V4209C.output.iterator();
   while (items.hasNext()) {
     item = items.next();
     bigString += item.get("F4301.OTOT_SUM") + "|"
   }
   jsonIn.put("concat",bigString);
  
   orchAttr.writeWarn(bigString);
   
   def jsonOut = new JsonBuilder(jsonIn).toString();
  
   return jsonOut;
}

When I run this now, I have an additional parameter at the bottom:

  "concat" : "756389.52|228918.32|216092.00|113000.00|24893.75|20000.00|2287.29|1327.50|1000.00|593.75|70.00|25.00|"

Nice variable name!

So, now I need to create a SR that is a connector type that is going to put this output variable “concat” into my other SR that does an external post to my web service!  Easy.

my orchestration looks like this:

image

My connector SR looks like this:

image

Note that the concat variable is defined in the output of the connector SR

So When I call my orchestration that calls the SR that calls an orchestration…

image

I get the output that I want.  The concatenation of the resultset in a string that I can send to my web service, that is great…  A long journey though!

Simple RTE observation - enhancement request

$
0
0
I've blogged a lot about RTE, because I think it's pretty cool.

There is one thing that I do not like...  The fact that it's a challenge to get more than one transaction server running.

Remember that your configuration of subscribers is half the battle - you can configure multiple subscribers and have them separated by name and environment - nicely.

Only subscribe to certain messages for certain environments and wow - everything looks nice from P90701A.

The main problem is that the RTE server polls the F90710 that is defined in the OCMs that you put in the transaction server config.

So, it's poll that table with a very simple SQL

SELECT MIN(ETEVNTSEQ) FROM SY910.F90710 WHERE (ETEVNTST = 3);

The same thing, said another way.

The transaction server does not check subscriber information, this is important.  When defining a subscriber and then a connection and events and active environments, remember that this is not going to completely define where messages will end up...  What do you mean?  I hear you ask.

It's not just triggers from the JDE kernels on the enterprise server that initiate the consumption of RTE, the txn server itself polls the F90710 using the statement above.


The following sequence of screens shows this slight calamity
My subscriber, defined for port 136 only

my subscriptions defined for port 136

My environments saying only PY910 messages

my RTE server in DV with the message!  Boo hoo!

It might be a simplistic point of view, but the transaction server could compare environments that are subscribed to and not grab the messages.  The transaction server could also look at F90706 etc to see if it was the machine that was referenced in the subscriber configuration and once again ignore the messages if this was the case.

Any of the two changes to the code would allow multiple transaction servers using a single set of configuration, much better!




Viewing all 541 articles
Browse latest View live