Page 1 of 1

VLF-ONE Persistent Application Strings

Posted: Tue Mar 14, 2017 4:20 am
by jyoung
I am having trouble getting persistent application string working.

In my logon handler, I set the Persistent_ApplicationString1 to the #UserNameToDisplay

Code: Select all

mthroutine name(CheckUserCredentials) options(*REDEFINE *RETURNS_MESSAGES)

define_com class(#VF_ELRETC) name(#TemporaryReturnCode)

#uSystemCommon.TraceEvent from(#COM_OWNER) text('CheckUserCredentials started.') systemtrace(False)

* ================= DEFAULT BEHAVIOUR =================
* Successful execution
#MajorReturnCode := OK

* User to display is the same as the one typed in the logon dialog
* #UserProfiletoCheck contains the real or derived user profile.
#UserNametoDisplay := #UserProfiletoCheck

* Temporarily disable framework authority
* TODO: Enable Framework Authority when everything gets working
#UseFrameworkObjectAuthority := false

* stash the userid in a persistent string, we will need to send this to the server for audit tracking
#Persistent_ApplicationString1 := #UserNametoDisplay
#Persistent_ApplicationString1 := ""
#Persistent_ApplicationString2 := ""
#Persistent_ApplicationString3 := ""
#Persistent_ApplicationString4 := ""
#Persistent_ApplicationString5 := ""

* OTHER CODE OMITTED

endroutine
In the ServerModule that I am trying to access it I have included a Session Identifier.

Code: Select all

begin_com role(*EXTENDS #PRIM_SRVM) sessionidentifier('VLFONE')
and defined the persistent fields

Code: Select all

define field(#Persistent_ApplicationString1) type(*NVARCHAR)
define field(#Persistent_ApplicationString2) type(*NVARCHAR)
define field(#Persistent_ApplicationString3) type(*NVARCHAR)
define field(#Persistent_ApplicationString4) type(*NVARCHAR)
define field(#Persistent_ApplicationString5) type(*NVARCHAR)

persist fields(#Persistent_ApplicationString1 #Persistent_ApplicationString2 #Persistent_ApplicationString3 #Persistent_ApplicationString4 #Persistent_ApplicationString5)
When I try to access the #Persistent_ApplicationString1 its always blank.

I know the framework is invoking the correct logon handler as I can step through it and see that the persistent string is getting set.

In the web page the framework is initialized with

Code: Select all

#VLF_ONE.uInitialize frameworkidentifer("EXPRESS_SYSTEM") logonhandlerid(VF_AC026O) passwordchangerid("") mtxtloaderid(UF_OMULTI) themecustomizerid(VLFTHEME) logonexpiry(90) logonheaderpanelid(VLFLOGO) logontrailerpanelid("")
One question is how does the logon handler know what session identifier to use to put the persistent strings into? I am not seeing anything that states what session to use. The example always referenced DF_T62H1O and DFT62SMO don't use a logon handler so I am missing how that connection is made.

Re: VLF-ONE Persistent Application Strings

Posted: Tue Mar 14, 2017 10:30 am
by MarkD
If you run the shipped DF_T62* demo programs the logon handler being used should be UF_OLOGON.

UF_OLOGON has this code to set the persistent strings to example values?
#Persistent_ApplicationString1 := "Example string 1"
#Persistent_ApplicationString2 := "Example string 2"
#Persistent_ApplicationString3 := "Example string 3"
#Persistent_ApplicationString4 := "Example string 4"
#Persistent_ApplicationString5 := "Example string 5"

All logon handlers, yours and UF_OLOGON, are all called by server module VF_SW100O and it has this session declaration:

Begin_Com Role(*EXTENDS #PRIM_SRVM) Sessionidentifier('VLFONE')

So when you execute the shipped DF_T62SMO, it runs withing the VLFONE session:

Begin_Com Role(*EXTENDS #PRIM_SRVM) Sessionidentifier('VLFONE')

That's what links the session data together.

Some questions come to mind:

Do the DF_T62* examples work correctly when used in the shipped demo framework?

Do you have a local and IBM i server versions of your logon program and are they in sync?


For me, sometimes adding tracing to your server side code can be more equivocal that debugging.

For example, adding this to you version of UF_OLOGON:

#uSystemCommon.TraceEvent From(#COM_OWNER) Text('Set #Persistent_ApplicationString1 to ' + #Persistent_ApplicationString1) Systemtrace(False)

Then execute with trace=Y on the start up URL and you should see the trace message arrives out at the client, or not, which is often instructive. If you want to add server side tracing to your other server modules let me know and I can run though how to do that.

Re: VLF-ONE Persistent Application Strings

Posted: Tue Mar 14, 2017 10:45 am
by MarkD
The easiest temporary way to trace any server side activity is to use MESSAGE commands.

As long as the client side command handler that called your server module does a

#AVFRAMEWORKMANAGER.avReceiveSystemMessageQueue Requester(#COM_OWNER)

when it completes, then your “trace” MESSAGESs should appear in the message area at the bottom of the command handler pane.

Re: VLF-ONE Persistent Application Strings

Posted: Wed Mar 15, 2017 1:41 am
by jyoung
Hi Mark,

Please allow me to spare myself the embarrassment of telling you why this was not working. ;)

I did get it to work by tracing the output instead of trying to debug it.

I could not find where the #uSystemCommon.TraceEvent output is written to, so I ended up hooking in my own server trace handler and using #SYS_APPLN instead, through which I was able to identify my mistake.

Regarding #VF_SY001X (SystemCommon Object), is there any information or documentation for it? Such as where does the trace output to and how to enable it? Should we use it instead of SYS_APPLN on the server?

Re: VLF-ONE Persistent Application Strings

Posted: Wed Mar 15, 2017 11:06 am
by MarkD
As it stands you cannot use the VLF’s internal serer side tracing capability unless your code was called by server module VF_SW100O – such as your logon handler or password changer.It is not currently designed to work in your own free standing server routines.

So, the simplest way to trace at the moment is to just use MESSAGE commands.

If pass a Boolean parameter into your server routines to condition the MESSAGE commands then you can leave them permanently in place, which might be useful in identifying production system issues. If you source that parameter from #avFrameworkManager.avTrace on the client then you have linked it to using Trace=Y on the URL.

The next step up in genericity would be to define a standard trace working list that you pass to every server module. You could have a method that adds traced details to it. After every server routine call completes you could route all the entries into the VLF’s trace by using #avFrameworkManager.avRecordTrace and then clear the trace list.
If you have customized singleton “managers” for your client code and your server code then all of that could be reduced to a few shared method calls.

I guess we should look to providing some stronger out-of-the-box tracing on the server side, something that aligns better with what the client side can do.