Monday, December 16, 2013

How to avoid timeouts with Oracle BPM loops

Say that you have a loop in your flow and you send some notification to all of your customers. This might be thousands of executions. And if things go wrong you may hit the timeout limit and end up with a suspended/halted bpm instance. To avoid this we can use a Timer in our loop even though we don’t need one.
Here is the idea.
In my environment the timeout is set to 30 seconds to simulate the issue and the solution. Each service call takes 10 seconds. The loop cardinality is 5. So it will timeout after the 3rd call.
Lets see.
Yep it faulted
As it can be seen in EM it made the 4th call but never came back.
Now lets add timers to our flow. I am adding a dummy timer that will hold the execution for a second.
Now we didn’t have any issues and process executed properly,


Update: I found out that this is called "Forced Dehydration" in Oracle terminology, more info

Sunday, December 15, 2013

How Parallel Is the Oracle Bpm's loop ?

I found out that  when you create a loop in your BPM flow and mark its mode as Parellel  it is actually not running in real parallel execution.
Instead it creates loop instances first and runs the 1st activity of all of them . Then it starts running the 2nd activity and so for..
In my test case I pass the service name  and loop counter to the WS and WS just prints the string input.
And here is the output :

Service : First Call :1
Service : First Call :2
Service : First Call :3
Service : First Call :4
Service : First Call :5
Service : Second Call :1
Service : Second Call :2
Service : Second Call :3
Service : Second Call :4
Service : Second Call :5
As it can be seen clearly that ot doesn’t execute in parallel. Meaning in case something goes wrong at one loop instance others won’t be executed until it is fixed. By the way if you wonder same applies to parallel executions that are forked at a gate as well.

Thursday, December 12, 2013

An error occurred while trying to retrieve audit trail for this instance. Please review log files for detailed reasons.

If you face this error while trying to access the BPM process instances in EM , there is a setting on the Adminserver that you need to increase. You should be seeing below error in admin server logs.

IOException occurred on socket: Socket[addr=egw-bpm1-mnad-nsc.wfs.com/10.10.224.65,port=8001,localport=43747]
 weblogic.socket.MaxMessageSizeExceededException: Incoming message of size: '10000080' bytes exceeds the configured maximum of: '10000000' bytes for protocol: 't3'.
weblogic.socket.MaxMessageSizeExceededException: Incoming message of size: '10000080' bytes exceeds the configured maximum of: '10000000' bytes for protocol: 't3'
at weblogic.socket.BaseAbstractMuxableSocket.incrementBufferOffset(BaseAbstractMuxableSocket.java:230)
at weblogic.rjvm.t3.MuxableSocketT3.incrementBufferOffset(MuxableSocketT3.java:351)

To resolve this set the below setting to a higher value. 

Maximum Message Size in the weblogic admin console by going to 
Servers >> MyServer >> Protocols >> General tab >> Max Message Size

Thursday, December 05, 2013

Get list of Data Souces on weblogic

In case you need to give the user option to select a data source before executing a query below might be helpful It will return a list of select items that contains the data sources under jdbc/ List list = new ArrayList(); try { InitialContext initialContext = new InitialContext(); if (initialContext != null) { NamingEnumeration ne = initialContext.list("jdbc"); while (ne.hasMore()) { NameClassPair nc = (NameClassPair)ne.next(); list.add(new SelectItem("jdbc/" + nc.getName())); } } }

Thursday, November 07, 2013

Logging web services request/response messages in WLS

This comes very handy while debugging an issue with Oracle BPM Suite Add those parameters to server start script or through the console change the startup parameters. -Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true -Dcom.sun.xml.internal.ws.transport.http.HttpAdapter.dump=true -Dcom.sun.xml.ws.transport.http.HttpAdapter.dump=true -Dcom.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump=true

Tuesday, May 14, 2013

Refreshing Data Controls When the BPM Payload is changed

As you all know by now that simple things can get complicated with JDeveloper. This is one of them,

While working with BPM you sometime need to alter the Payload type and add new attributes to it. In able make those new attributes visible at the ADF taskflow side you need to refresh the data control definitions. This is a very simple, straighforward task.

The issue comes around when you work with a team , where each member uses a different folder structure for their dev box. The project that you have the ADF pages and taskflows keeps a reference to the payload's schema definition files. The problem is this reference uses an absolute path instead of a relative path. So once you move your workspace to a different folder you can no longer do a "Refresh Data Control". To workaround this open DataControls.dcx file and update the references to the PayLoad XSD files.

Wednesday, December 01, 2010

Adhoc SQL Query Addon For Your ADF 11g Application

It is very common that once you release your application you may need to execute some SQL queries through your application for trouble shooting purposes etc.


I wanted to try how possible to implement  this in ADF and here is what I found in a very primitive way.

I have a text area for the user to enter the SQL query and when the execute button is clicked the results will be displayed in the table below.



















In able to achieve this I am creating a View Object from a SQL statement in my AM.

AM code ...
    @Override
    protected void prepareSession(Session session) {
        super.prepareSession(session);
        
        if (findViewObject("SQLVo") == null) {
            createViewObjectFromQueryStmt("SQLVo",
                                                      " select 1 from dual  ");
        } 
        
         

    }
    
    public void executeSQL(String pSQLQuery){
        ViewObjectImpl vo = null;
        if (findViewObject("SQLVo") != null) {
            findViewObject("SQLVo").remove();
            System.out.println("Removing ");
        } 
        
        vo= (ViewObjectImpl) createViewObjectFromQueryStmt("SQLVo",pSQLQuery); 
        
        vo.executeQuery();
        System.out.println(vo.getEstimatedRowCount());
    }

   

My Page
<f:view>
    <af:document id="d1">
      <af:messages id="m1"/>
      <af:form id="f1">
        <af:panelStretchLayout topHeight="187px" id="psl1">
          <f:facet name="top">
            <af:panelFormLayout id="pfl1">
              <af:inputText value="#{bindings.pSQLQuery.inputValue}"
                            label="Query"
                            required="#{bindings.pSQLQuery.hints.mandatory}"
                            columns="60"
                            maximumLength="#{bindings.pSQLQuery.hints.precision}"
                            shortDesc="#{bindings.pSQLQuery.hints.tooltip}"
                            id="it1" rows="5">
                <f:validator binding="#{bindings.pSQLQuery.validator}"/>
              </af:inputText>
              <af:commandButton actionListener="#{bindings.executeSQL.execute}"
                                text="Execute"
                                disabled="#{!bindings.executeSQL.enabled}"
                                id="cb1" partialSubmit="true"/>
            </af:panelFormLayout>
          </f:facet>
          <f:facet name="center">
            <!-- id="af_one_column_header_stretched"  -->
            <af:panelCollection id="pc1" partialTriggers="::cb1">
              <f:facet name="menus"/>
              <f:facet name="toolbar"/>
              <f:facet name="statusbar"/>
              <af:table rows="#{bindings.SQLVo.rangeSize}"
                        fetchSize="#{bindings.SQLVo.rangeSize}" var="row"
                        rowBandingInterval="0"
                        value="#{bindings.SQLVo.collectionModel}"
                        rowSelection="single" id="t1" partialTriggers="::cb1">
                <af:forEach items="#{bindings.SQLVoIter.attributeDefs}" var="def">
                  <af:column headerText="#{def.name}" sortable="false" id="c1">
                    <af:outputText value="#{row[def.name]}" id="ot1"/>
                  </af:column>
                </af:forEach>
              </af:table>
            </af:panelCollection>
          </f:facet>
        </af:panelStretchLayout>
      </af:form>
    </af:document>
  </f:view>
My Page Definition

<executables>
    <iterator id="SQLVoIter" Binds="SQLVo" DataControl="AppModuleDataControl"
              Refresh="always" RangeSize="25"/>
    <variableIterator id="variables">
      <variable Type="java.lang.String" Name="executeSQL_pSQLQuery"
                IsQueriable="false"/>
    </variableIterator>
  </executables>
  <bindings>
    <methodAction id="executeSQL" RequiresUpdateModel="true"
                  Action="invokeMethod" MethodName="executeSQL"
                  IsViewObjectMethod="false" DataControl="AppModuleDataControl"
                  InstanceName="AppModuleDataControl.dataProvider">
      <NamedData NDName="pSQLQuery" NDType="java.lang.String"
                 NDValue="${bindings.executeSQL_pSQLQuery}"/>
    </methodAction>
    <attributeValues IterBinding="variables" id="pSQLQuery">
      <AttrNames>
        <Item Value="executeSQL_pSQLQuery"/>
      </AttrNames>
    </attributeValues>
   
     <tree IterBinding="SQLVoIter" id="SQLVo">
      <nodeDefinition Name="Dummy">
      </nodeDefinition>
    </tree>
  </bindings>