Thursday, August 25, 2011

Best Description By JDeveloper.

Wish JDev would have been so precise for all the errors it throws sometimes.
Check this dialog, it does not need any explanation:



Cheers.

Wednesday, August 24, 2011

Things To Remember While Working With XML Menu Model.

Notes taken from DEV Guide:

1. Each node in the page hierarchy can be a parent and a child node at the same time, and each item node in the page hierarchy corresponds to a page.
2. A group node allows you to retain a hierarchy without needing to create pages for nodes that are simply aggregates for their children nodes. In other words, you dont need to create pages for Group Nodes.
3. Difference between Group Node & Shared Node:
Group Node: Groups child components; the groupNode itself does no navigation. Child nodes node can be itemNode or another groupNode.
Shared Node: References another XMLMenuModel instance. A sharedNode element is not a true node; it does not perform navigation nor does it render anything on its own.

In other words, a shared node can point to a menu model that begins with a group node.
Here is an example:

Root (Level 0) Menu code:
<?xml version="1.0" encoding="windows-1252" ?>
<menu xmlns="http://myfaces.apache.org/trinidad/menu">
  <itemNode id="itemNode_Home" label="Home" action="adfMenu_Home" focusViewId="/Home">
    <sharedNode ref="#{level1_menu}"/>
    <!--<itemNode id="itemNode_PartList" label="label_PartList" action="adfMenu_PartList" focusViewId="/PartList"/>-->
  </itemNode>
  <itemNode id="itemNode_Logout" label="Logout" action="adfMenu_Logout" focusViewId="/Logout"/>
  <itemNode id="itemNode_Help" label="Help" action="adfMenu_Help" focusViewId="/Help"/>
</menu>

Level 1 Menu code:

<?xml version="1.0" encoding="windows-1252" ?>
<menu xmlns="http://myfaces.apache.org/trinidad/menu">
  <itemNode id="itemNode_Main" label="Main" action="adfMenu_Main" focusViewId="/Main"/>
  <itemNode id="itemNode_ContactInformation" label="ContactInformation" action="adfMenu_ContactInformation"
            focusViewId="/ContactInformation"/>
  <sharedNode ref="#{level2_menu}"/>
</menu>

Level 2 Menu Code:

<?xml version="1.0" encoding="windows-1252" ?>
<menu xmlns="http://myfaces.apache.org/trinidad/menu">
  <groupNode id="itemNode_PartList" label="PartList" idref="itemNode_Inprocess">
    <itemNode id="itemNode_Complete" label="Complete" action="adfMenu_Complete" focusViewId="/Complete"/>
    <itemNode id="itemNode_ImportFile" label="ImportFile" action="adfMenu_ImportFile" focusViewId="/ImportFile"/>
    <itemNode id="itemNode_Inprocess" label="Inprocess" action="adfMenu_Inprocess" focusViewId="/Inprocess"/>
  </groupNode>
</menu>

Inaddition, there is not page for PartList node.

4. The value attribute of all navigation panes in a page template should reference only a root menu model and not any menu models referenced through shared nodes.  For example, if you use a shared node in your main XMLMenuModel element, JDeveloper would have created managed bean configurations for the shared node and the root XMLMenuModel bean that consumes the shared model. The shared model managed bean is automatically incorporated into the root menu model managed bean as the menu tree is parsed at startup.

Thursday, August 18, 2011

ADF Integration With SOA 1 - Business Events.

While working with Business Events (BEs), I faced some issues. In this blog, I am documenting whatever I did to successfully raise BEs.
I have divided this blog into 3 sections:

  1. Setup Required for BEs.
  2. Code Development.
  3. Deployment and Running the application to raise BEs.
For this example, I have used two servers:
  1. JDev's Integrated WLS (IWLS) for ADF application that raises the BE.
  2. Standalone SOA Server - Separate server where SOA application ( that will consume the BE raised by ADF app ) will be deployed.
Both the server are using my local Oracle Database for EDN. So, same EDN is shared by both the servers.
Hence, you can deploy each application on separate servers.

Setup Required for BEs.

Download and install SOA extension on JDev so that IWLS will have the libraries required for BE. Specifically, 'oracle.soa.workflow.wc'. To download SOA extension, go to Help->Check For Updates:


Do not uncheck 'Oracle Fusion Middleware Products' & 'Official Oracle Extensions and Updates', and click Next.


Select SOA extension and click Finish. Since I have already done it, so my JDev is not showing that entry now so can't add that snapshot.

The SOA extension will take some time to download. Once that is done, start the server, and in the IWLS console, you will be able to see an entry for 'oracle.soa.workflow.wc' library in the Deployments page.


Without this library, while raising BEs, you will get the following error:

<Utils> <buildFacesMessage> ADF: Adding the following JSF error message: oracle/fabric/blocks/event/BusinessEventConnectionFactory
java.lang.NoClassDefFoundError: oracle/fabric/blocks/event/BusinessEventConnectionFactory
at oracle.jbo.server.EventInvocation.raiseEvent(EventInvocation.java:513)
at oracle.jbo.server.EntityImpl.raiseEvents(EntityImpl.java:7724)
at oracle.jbo.server.EntityImpl.afterCommit(EntityImpl.java:7329)
at oracle.jbo.server.DBTransactionImpl.doAfterCommit(DBTransactionImpl.java:2285)
at oracle.jbo.server.DBTransactionImpl.commitInternal(DBTransactionImpl.java:2176)
at oracle.jbo.server.DBTransactionImpl.commit(DBTransactionImpl.java:2369)
at oracle.adf.model.bc4j.DCJboDataControl.commitTransaction(DCJboDataControl.java:1608)
. . .
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2277)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2183)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1454)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:207)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:176)
Caused by: java.lang.ClassNotFoundException: oracle.fabric.blocks.event.BusinessEventConnectionFactory
at weblogic.utils.classloaders.GenericClassLoader.findLocalClass(GenericClassLoader.java:297)
at weblogic.utils.classloaders.GenericClassLoader.findClass(GenericClassLoader.java:270)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at weblogic.utils.classloaders.GenericClassLoader.loadClass(GenericClassLoader.java:179)
... 65 more

By installing SOA extenstion to JDev, we can use JDev's IWLS to raise events successfully.
Apart from this, you need to create the following two Data Sources(DSs) on IWLS:
  • EDNDataSource (XA DS )
  • EDNLocalTxDataSource (Non-XA DS)


If you don't define these DSs, you will get the following messages in JDev log while raising BEs:

INFO: Looking for BusinessEventConnectionFactory
INFO: Looking for EDN-DB JNDI configuration to create SAQRemoteBusinessEventConnectionFactory.
INFO: Unable to create SAQRemoteBusinessEventConnectionFactory: [jdbc/EDNSource or jdbc/EDNDataSource] undefined.
INFO: Looking for EDN-JMS JNDI configuration to gcreate JMSRemoteBusinessEventConnectionFactory.
INFO: Unable to create JMSRemoteBusinessEventConnectionFactory: [java:comp/UserTransaction] undefined.
INFO: Unable to create JMSRemoteBusinessEventConnectionFactory: [jms/fabric/EDNConnectionFactory] undefined.
INFO: Failed to get ConnectionFactory instance.
. . .
<JmsBusinessEventBusMessages> <warnUsingGlobalDatasourecForLocal> Local Tx Datasource not found, using XA datasource. Please update your configuration.

Once you define these DSs successfully, you wont get these messages in JDev log, and are required for successfully raising BEs.

EDNSource is not required if you define EDNDataSource. Looks like ENDSource is an old name of the driver and the new name is EDNDataSource.

In my case, SOA Server is already having these DSs, so I just replicated those DSs on IWLS.
For more details about DSs, please refer to the following forum post:

Code Development.

I have created a small application over SCOTT.EMP table to raise a BE on employee creation.


EmpEO is based on SCOTT.EMP, and added to AppModule through EmpVO. Using the Business Events section of EmpEO, I defined and published the following event:


The following is the event definition:


And here is now the event is published:


After that, I created a simple page for EmpVO, and added two buttons, one for row insertion, and second one for commit:


Then, in the weblogic-application.xml, visible in Descriptors->META-INF folder in Application Resources, I added the following entry:


This is done so that we can get access to 'oracle.fabric.blocks.event.BusinessEventConnectionFactory'.
If we straight away add 'SOA Runtime' or 'SOA Workflow' library to our model project, some how the class is not accessible, so getting this from the server itself.

Then created a small SOA application to subscribe to the event using Mediator, and writing the payload to a text file using a File Adapter:


The Mediator in the above figure points to the EmpEO.edl and EmpEO.xsd files of the previously created ADF application. The mediator passes the payload to BPEL:


And here is the transformation:


The following image shows the structure of BPEL, which transfers to payload to File Adapter:

And File Adapter writes the paylaod to a file in C:\TEMP folder:

Using the EmpEOs schema:

So, now lets run the application to raise BEs.

Deployment and Running the application to raise BEs.

Deploy the SOA application to the standalone SOA Server:


And run the ADF Application using CreateEmployee.jspx. Click 'CreateInsert' to insert a row in the table as shown below:

After entering the data, Click Commit. The BE is raised, and you can confirm by querying 'AQ$EDN_EVENT_QUEUE_TABLE' view:
If there is a consumer, like SOA app in our case, the records get vanished after a min or so, and SOA app writes the following paylaod to a text file as expected:

Done.

JDev Release 11.1.1.4