The Tester for ADF BC is a very handy tool, to verify the correctness of the Business Components we have created. However, there are times when the Tester is not useful: when the queries are somehow dependent on a database context. For example: if VPD (virtual private database) has been used to implement horizontal authorization rules (a user can only see a limited number of records), the database typically requires some context to be set. The name of the current user for example should be set in an Application Context before queries can successfully be executed. In ADF BC terms this boils down to implementing a subclass for the ApplicationModuleImpl that overrides the prepareSession() method that sets this context. If the web-application has been made secure, for example with JAAS, we can get the current username from the session object in ADF BC.
However, this information is not available when we use the Tester, neither do we have the Web Application running to call the ApplicationModuleImpl to make these settings. So, does this render the Tester completely useless? Well, at first I thought so. But then I came up with a little trick.
I have a database package APP_CONTEXT with a procedure set_current_user( p_username in varchar2) that should be called before any queries are executed, in order to give the VPD policies a chance to return any meaningful information.
The trick consists of the following steps:
- implement a function that takes a varchar2 input parameter (the username) and calls the app_context.set_current_user procedure and returns a varchar2
- create a simple readonly ViewObject that selects from that function – and takes a bind-parameter to pass on to the function
- add this ViewObject to the Application Module’s data model
- run the tester – before accessing any ViewObjects, first query the new readonly ViewObject: a popup message is presented that asks for the value of the bind-parameter (the name of the current user) and the query is executed, calling the function and indirectly setting the user in the context
- now all other queries will be with the proper context values set up
Step 1: The function set_user_context
The function I created
function set_user_context
(p_username in varchar2)
return varchar2
is
begin
app_context.set_current_user(p_username);
return p_username;
end;
Step 2: Create the ViewObject
The Read Only ViewObject SetUserContextView:
select set_user_context(:currentuser) currentUser
from dual
Also define the Bind variable currentuser – if you like with a default value
The other steps are self-explanatory.
Thanks Steve, So far for me thinking of a clever trick.. Well, if you want to set some database context, other than the current user – could this still be a handy way of working?
Lucas, when your AM is configured as mentioned in section 30.4.1 “How to Configure Security in an Oracle ADF Business Components Application” of the ADF Developer’s Guide for Forms/4GL Developers, when you run the tester a JAAS authentication box will popup and while running the tester your ADFBC components will be running in the same JAAS-authenticated environment as when running in a web container. Try running the SRDemo Sample’s application module and authenticate as “sking” (password “welcome) and you’ll see that the various bits of the application that depend on accessing the current user (as mentioned in section 9.8 “How to Reference Information About the Authenticated User” of the Dev Guide). Have fun. Also check out this blog post (http://radio.weblogs.com/0118231/stories/2006/06/23/dynamicallyAssigningNamedBindVariableDefaultValues.html) for some code that generically allows you to default the value of a specially-hinted-with-custom-properties bind variable with the name of the currently logged in user.