Monday, November 4, 2013

URL Free Composite Code - Errors

We were trying to achieve URL free code in 11g composites, as this is standard thing to do in any programming language. We did consider all the options mentioned available as this, but anyways first thing is to make code URL free, so URL can be changed without doing any code deployment and code and binary is completely portable to any other environment - like jar or binary files.

For example, if ProcessA is calling ProcessB, we need to change reference of ProcessB.

ProcessA : composite.xml  

  <reference name="ProcessB" ui:wsdlLocation="PROCESS-B-ABSTRACT-WSDL">
    <interface.wsdl interface="http://xmlns.oracle.com/TokenTesting/ProjectB/BPELProcessB#wsdl.interface(BPELProcessB)"/>
    <binding.ws port="http://xmlns.oracle.com/TokenTesting/ProjectB/BPELProcessB#wsdl.endpoint(bpelprocessb_client_ep/BPELProcessB_pt)"
                location="PROCESS-B-RUNTIME-WSDL-WITH-BINDINGS" soapVersion="1.1">
        <property name="weblogic.wsee.wsat.transaction.flowOption" type="xs:string" many="false">WSDLDriven</property>
    </binding.ws>
  </reference>


Process A : componentType

  <reference name="ProcessB" ui:wsdlLocation="PROCESS-B-ABSTRACT-WSDL">
    <interface.wsdl interface="http://xmlns.oracle.com/TokenTesting/ProjectB/BPELProcessB#wsdl.interface(BPELProcessB)"/>
  </reference>

We decided to keep ProcessB runtime WSDL file along with bindings (which you can get from EM console) to MDS, so reference looked like this.

ProcessA : composite.xml 

  <reference name="ProcessB" ui:wsdlLocation="oramds:/apps/processb/processb.wsdl">
    <interface.wsdl interface="http://xmlns.oracle.com/TokenTesting/ProjectB/BPELProcessB#wsdl.interface(BPELProcessB)"/>
    <binding.ws port="http://xmlns.oracle.com/TokenTesting/ProjectB/BPELProcessB#wsdl.endpoint(bpelprocessb_client_ep/BPELProcessB_pt)"
                location="oramds:/apps/processb/processb.wsdl" soapVersion="1.1">
        <property name="weblogic.wsee.wsat.transaction.flowOption" type="xs:string" many="false">WSDLDriven</property>
    </binding.ws>
  </reference>


Process A : componentType
  <reference name="ProcessB" ui:wsdlLocation="oramds:/apps/processb/processb.wsdl">
    <interface.wsdl interface="http://xmlns.oracle.com/TokenTesting/ProjectB/BPELProcessB#wsdl.interface(BPELProcessB)"/>
  </reference>

Once that is done, you can either have valid runtime endpoint URL in , or dynamic endpoint URL by reading it from config file (for AIA it is OOTB but it can be done in pure SOA as well).


Errors
We faced different errors while working on this.

1. Null Pointer Exception:

Jdeveloper shows warning during compilation:

ProjectA\composite.xml:30: warning: Failed to Find Binding "ProcessB":
    "{http://xmlns.oracle.com/TokenTesting/ProjectB/BPELProcessB}BPELProcessB_pt" in WSDL Manager

While executing from EM, it shows following error:

java.lang.NullPointerException
        at java.util.concurrent.ConcurrentHashMap.put(ConcurrentHashMap.java:1058)
        at oracle.integration.platform.blocks.soap.AbstractWebServiceBindingComponent.dispatchRequest(AbstractWebServiceBindingComponent.java:521)
        at oracle.integration.platform.blocks.soap.WebServiceExternalBindingComponent.processOutboundMessage(WebServiceExternalBindingComponent.java:287)
        at oracle.integration.platform.blocks.soap.WebServiceExternalBindingComponent.sendSOAPMessage(WebServiceExternalBindingComponent.java:1191)
        at oracle.integration.platform.blocks.soap.WebServiceExternalBindingComponent.request(WebServiceExternalBindingComponent.java:785)
        at oracle.integration.platform.blocks.mesh.SynchronousMessageHandler.doRequest(SynchronousMessageHandler.java:139)
        at oracle.integration.platform.blocks.mesh.MessageRouter.request(MessageRouter.java:182)
        at oracle.integration.platform.blocks.mesh.MeshImpl.request(MeshImpl.java:190)
        at sun.reflect.GeneratedMethodAccessor3438.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
        at oracle.integration.platform.metrics.PhaseEventAspect.invoke(PhaseEventAspect.java:71)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
        at $Proxy361.request(Unknown Source)
        at oracle.fabric.CubeServiceEngine.requestToMesh(CubeServiceEngine.java:858)
        at com.collaxa.cube.ws.WSInvocationManager.invoke(WSInvocationManager.java:267)
        at com.collaxa.cube.engine.ext.common.InvokeHandler.__invoke(InvokeHandler.java:1099)
        at com.collaxa.cube.engine.ext.common.InvokeHandler.handleNormalInvoke(InvokeHandler.java:594)
        at com.collaxa.cube.engine.ext.common.InvokeHandler.handle(InvokeHandler.java:132)
        at com.collaxa.cube.engine.ext.bpel.common.wmp.BPELInvokeWMP.__executeStatements(BPELInvokeWMP.java:74)
        at com.collaxa.cube.engine.ext.bpel.common.wmp.BaseBPELActivityWMP.perform(BaseBPELActivityWMP.java:173)
        at com.collaxa.cube.engine.CubeEngine.performActivity(CubeEngine.java:2718)
        at com.collaxa.cube.engine.CubeEngine._handleWorkItem(CubeEngine.java:1197)
        at com.collaxa.cube.engine.CubeEngine.handleWorkItem(CubeEngine.java:1100)
        at com.collaxa.cube.engine.dispatch.message.instance.PerformMessageHandler.handleLocal(PerformMessageHandler.java:76)
        at com.collaxa.cube.engine.dispatch.DispatchHelper.handleLocalMessage(DispatchHelper.java:251)
        at com.collaxa.cube.engine.dispatch.DispatchHelper.sendMemory(DispatchHelper.java:330)
        at com.collaxa.cube.engine.CubeEngine.endRequest(CubeEngine.java:4652)
        at com.collaxa.cube.engine.CubeEngine.endRequest(CubeEngine.java:4583)
        at com.collaxa.cube.engine.CubeEngine._createAndInvoke(CubeEngine.java:714)
        at com.collaxa.cube.engine.CubeEngine.createAndInvoke(CubeEngine.java:559)
        at com.collaxa.cube.engine.ejb.impl.CubeEngineBean.createAndInvoke(CubeEngineBean.java:103)
        at com.collaxa.cube.engine.ejb.impl.CubeEngineBean.syncCreateAndInvoke(CubeEngineBean.java:145)
        at com.collaxa.cube.engine.ejb.impl.bpel.BPELEngineBean.syncCreateAndInvoke(BPELEngineBean.java:112)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)

OR

java.lang.NullPointerException
        at oracle.integration.platform.blocks.soap.WebServiceExternalBindingComponent.getInvocationMetadata(WebServiceExternalBindingComponent.java:928)
        at oracle.integration.platform.blocks.soap.WebServiceExternalBindingComponent.request(WebServiceExternalBindingComponent.java:530)
        at oracle.integration.platform.blocks.mesh.SynchronousMessageHandler.doRequest(SynchronousMessageHandler.java:139)
        at oracle.integration.platform.blocks.mesh.MessageRouter.request(MessageRouter.java:179)
        at oracle.integration.platform.blocks.mesh.MeshImpl.request(MeshImpl.java:155)
        at sun.reflect.GeneratedMethodAccessor4746.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
        at oracle.integration.platform.metrics.PhaseEventAspect.invoke(PhaseEventAspect.java:71)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
        at $Proxy348.request(Unknown Source)
        at oracle.fabric.CubeServiceEngine.requestToMesh(CubeServiceEngine.java:824)
        at com.collaxa.cube.ws.WSInvocationManager.invoke(WSInvocationManager.java:263)
        at com.collaxa.cube.engine.ext.common.InvokeHandler.__invoke(InvokeHandler.java:1056)
        at com.collaxa.cube.engine.ext.common.InvokeHandler.handleNormalInvoke(InvokeHandler.java:583)
        at com.collaxa.cube.engine.ext.common.InvokeHandler.handle(InvokeHandler.java:130)
        at com.collaxa.cube.engine.ext.bpel.common.wmp.BPELInvokeWMP.__executeStatements(BPELInvokeWMP.java:75)
        at com.collaxa.cube.engine.ext.bpel.common.wmp.BaseBPELActivityWMP.perform(BaseBPELActivityWMP.java:158)
        at com.collaxa.cube.engine.CubeEngine._performActivity(CubeEngine.java:2463)
        at com.collaxa.cube.engine.CubeEngine.performActivity(CubeEngine.java:2334)
        at com.collaxa.cube.engine.CubeEngine.handleWorkItem(CubeEngine.java:1116)
        at com.collaxa.cube.engine.dispatch.message.instance.PerformMessageHandler.handleLocal(PerformMessageHandler.java:73)
        at com.collaxa.cube.engine.dispatch.DispatchHelper.handleLocalMessage(DispatchHelper.java:220)
        at com.collaxa.cube.engine.dispatch.DispatchHelper.sendMemory(DispatchHelper.java:328)
        at com.collaxa.cube.engine.CubeEngine.endRequest(CubeEngine.java:4350)
        at com.collaxa.cube.engine.CubeEngine.endRequest(CubeEngine.java:4282)
        at com.collaxa.cube.engine.CubeEngine.createAndInvoke(CubeEngine.java:679)
        at com.collaxa.cube.engine.ejb.impl.CubeEngineBean.createAndInvoke(CubeEngineBean.java:103)
        at com.collaxa.cube.engine.ejb.impl.CubeEngineBean.syncCreateAndInvokeParticipate(CubeEngineBean.java:181)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)

Solution: Make sure runtime WSDL is updated in referred in binding section. If it is abstract WSDL, it will throw this error message.


2. Transport can not be determined from uri REPLACE_WITH_ACTUAL_URL

oracle.fabric.common.FabricInvocationException: Unable to invoke endpoint URI "REPLACE_WITH_ACTUAL_URL" successfully 
due to: java.lang.IllegalArgumentException: Transport can not be determined from uri REPLACE_WITH_ACTUAL_URL    

Please make sure you have added soapVersion="XYZ" and weblogic.wsee.wsat.transaction.flowOption, which usually gets removed when you hand edit composite.xml or upgrade it from 10g to 11g.

  <reference name="ProcessB" ui:wsdlLocation="PROCESS-B-ABSTRACT-WSDL">
    <interface.wsdl interface="http://xmlns.oracle.com/TokenTesting/ProjectB/BPELProcessB#wsdl.interface(BPELProcessB)"/>
    <binding.ws port="http://xmlns.oracle.com/TokenTesting/ProjectB/BPELProcessB#wsdl.endpoint(bpelprocessb_client_ep/BPELProcessB_pt)"
                location="PROCESS-B-RUNTIME-WSDL-WITH-BINDINGS" soapVersion="1.1">
        <property name="weblogic.wsee.wsat.transaction.flowOption" type="xs:string" many="false">WSDLDriven</property>
    </binding.ws>
  </reference>



Thursday, October 31, 2013

Disabling AIA FP WS Security Policyset

AIA FP comes with global web services security policy set as part of foundation pack installation as below.






Policy sets gets attached to your composite based on name. e.g. "oracle/aia_wss10_saml_token_client_policy_OPT_ON" policy gets attached to all composites with ABCS in it, as per below screen shots. 



WS security header would be required if it is getting called from outside (as I believe internal calls would be supplied with WS security stuff as part of client policies). If you have policy enabled, you can use blog to when you are calling the service from external source.

To disable the policy set attached to your Composites, you can individually goto each Policy Set, and disable it, or run following script:




cd $SOA_HOME/common/bin
wlst
connect('weblogic','***','t3://admin-host:admin-port')

beginRepositorySession()
modifyPolicySet('AIA_EBS_WSClientPolicySet')
enablePolicySet(false)
commitRepositorySession() 

beginRepositorySession()
modifyPolicySet('AIA_EBF_WSClientPolicySet')
enablePolicySet(false)
commitRepositorySession() 

beginRepositorySession()
modifyPolicySet('AIA_ABCS_WSClientPolicySet')
enablePolicySet(false)
commitRepositorySession() 

beginRepositorySession()
modifyPolicySet('AIA_Producer_WSClientPolicySet')
enablePolicySet(false)
commitRepositorySession() 

beginRepositorySession()
modifyPolicySet('AIA_ABF_WSClientPolicySet')
enablePolicySet(false)
commitRepositorySession() 

beginRepositorySession()
modifyPolicySet('AIA_B2BCS_WSClientPolicySet')
enablePolicySet(false)
commitRepositorySession() 

beginRepositorySession()
modifyPolicySet('AIA_Consumer_WSClientPolicySet')
enablePolicySet(false)
commitRepositorySession() 

beginRepositorySession()
modifyPolicySet('AIA_Producer_WSServicePolicySet')
enablePolicySet(false)
commitRepositorySession() 

beginRepositorySession()
modifyPolicySet('AIA_ABCS_WSServicePolicySet')
enablePolicySet(false)
commitRepositorySession() 

beginRepositorySession()
modifyPolicySet('AIA_ABF_WSServicePolicySet')
enablePolicySet(false)
commitRepositorySession() 

beginRepositorySession()
modifyPolicySet('AIA_EBF_WSServicePolicySet')
enablePolicySet(false)
commitRepositorySession() 

beginRepositorySession()
modifyPolicySet('AIA_Adapter_WSServicePolicySet')
enablePolicySet(false)
commitRepositorySession() 

beginRepositorySession()
modifyPolicySet('AIA_EBS_WSServicePolicySet')
enablePolicySet(false)
commitRepositorySession() 

beginRepositorySession()
modifyPolicySet('AIA_B2BCS_WSServicePolicySet')
enablePolicySet(false)
commitRepositorySession() 

beginRepositorySession()
modifyPolicySet('AIA_Adapter_WSClientPolicySet')
enablePolicySet(false)
commitRepositorySession() 

beginRepositorySession()
modifyPolicySet('AIA_Consumer_WSServicePolicySet')                          
enablePolicySet(false)
commitRepositorySession() 


In EM console, sometime you have to re-login or go to one of the policy sets, so that it will refresh the flag and it will show all policy sets disabled.

We also ended up disabling Policy attached to individual Composite, as it doesn't allow disabling Policy via WLST like it does for Policy Set

enableWebServicePolicy(None, 'default/AIASessionPoolManager[1.0]', 'soa', 'client', 'AIASessionPoolManager', 'oracle/aia_wss_saml_or_username_token_service_policy_OPT_ON', false, None )
enableWebServicePolicy(None, 'default/AIAErrorTaskAdministrationProcess[1.0]', 'soa', 'aiaerrortaskadministrationprocess_client_ep', 'AIAErrorTaskAdministrationProcess_pt', 'oracle/aia_wss_saml_or_username_token_service_policy_OPT_ON', false, None )
enableWebServicePolicy(None, 'default/AIAAsyncErrorHandlingBPELProcess[1.0]', 'soa', 'client', 'AIAAsyncErrorHandlingBPELProcess', 'oracle/aia_wss_saml_or_username_or_http_token_service_policy_OPT_ON', false, None )



if you get error : "Try to use server name with application name. Multiple server targets deployed for application", refer to this blog

Saturday, October 12, 2013

Configurable settings and endpoint replacements - II

Almost a year ago, I blogged about Configurable settings and endpoint replacements , just want to reiterate as few more options are available for same functionality.

It feels like a very basic fundamental problem, which I would describe as, a configuration setting (be a URL or anything else), should be :
  • Must not be hard coded inside your code or binary
  • Must be able to replace it from environment to environment, and changing the those value must not cause server to restart

Java or any programming language has solved this problem tens of years ago, but Oracle keep seem to be providing one after another solution for last 10 years in SOA 10g/11g, and makes it really complicated problem than it sounds..

Configuration Settings

DVM
Pros

  • Stored in MDS
  • Changes are independent of deployment
  • Nice UI for update
Cons
  • Hard to modularize per Composite
  • If managed via both UI and SVN, it can quickly can get out of sync in multiple environment.
  • Not too sure about what level of caching is done


DB Lookup (may be with custom XSL)
  • Probably a bit more overhead vs having things in memory


AIA Configuration Properties (More info: http://chintanblog.blogspot.com/2012/10/aia-configuration-and-dynamic.html)
 Pros
  • MDS stored
  • Changes are independent of deployment
  • Different level of modularization - System/System Module/Service
Cons
  • No UI to make changes - hopefully in future release


Preference along with config plan (More info: http://chintanblog.blogspot.com/2012/06/bpel-preference-11g.html)
Pros
  • Run time changes via Mbean browser and changes can withstand server restart
Cons
  • Modularization is not flexible (e.g. two composite cannot share same property)
  • Changes via MBean are still temporary. Deployment will overwrite changes from composite (or config plan).
  • Have to keep config plan in sync with UI changes



Code migration and reference to end point URL
Custom search/replacement
Pros

  • Much better control, as it is raw search and replace
Cons
  • Custom scripting
  • Unless it is highly sophisticated, search term has to be known in advance
  • It breaks my principal #1 - why hardcode stuff in the code at first place?

Token Replacement (link)
Pros:
Cons:




  • Only works in specific files and specific section of composite.xml
  • Requires server restart
  • Can not be used for config other than binding.ws URL

Configuration Plan
Pros

  • OOTB, and it is xpath based replace so no need for search term
Cons
  • It breaks my principal #1 - why hardcode stuff in the code at first place?
  • have to manage one per env
  • If composite is constantly changing, it is really hard to manage multiple plans
  • No support for runtime URL change


Dynamic Partnerlink Lookup (DPL) - using AIAConfig (More info : link)
Pros

  • Centralized config for all end points (and preference) - better governance
  • OOTB functions for lookup and merge during deployment
  • Just one MDS stored file
Cons
  • Changes requires MDS update via script and reloading via AIA console
  • No UI to make changes - hopefully in future release
  • Only supported in AIA, if not AIA, need to have custom XSL function to support same functionality 
  • It comes close to what I would like to have, but involves entire AIA FP infrastructure to be installed plus the licensing cost


Oracle Service Registry (OSR)
  • It's dead, man, get over with it.

Token Replacement in SOA 11g

Since 11.1.1.7, along with what has been previously available (http://chintanblog.blogspot.com/2012/10/configurable-settings-and-endpoint.html) e.g. DVM, DB Lookup, AIA Config, Preference, Config Plan and Dynamic Partnerlink Lookup, Token replacement has been added and it claim to to solve similar problem.

How to use it

Define the Tokens in Enterprise Manager
As shown below, you can create tokens in EM console. Defined tokens gets stored in $DOMAIN_HOME/config/fmwconfig/mdm-url-resolver.xml file, unless you overwrite via -Doracle.soa.url.resolver.properties.file.




Once, it is done, you can use than in binding section of the composite.xml file, as shown below. Token will get replaced at run time.


It looks great at first glance, but from my opinion it is one more failed attempt to solve one very fundamental problem. Here are the issues I see:
  • Requires server restart for change in value of Token
  • Only works in composite.xml - binding sections
    • Even in Binding section, it won't work for endpointURI as below

    • Therefore, it won't work for preference replacement (e.g. below)

    • It won't work if you have live WSDL stored in MDS. It is quite common to have both ui:wsdlLocation and binding.ws location, both as MDS location. However, if you use token inside MDS wsdl, this will not work 


Friday, September 6, 2013

Change password in weblogic datasource / connection pool without restarting entire weblogic

  • Change the password in database
  • Change the password in connection pool on WebLogic Console for a specific datasource 

  • Untarget the datasource from all servers
 
  • Retarget the datasource to all servers where it was configured before
  • Shutdown Datasource
  • Start Datasource

SOA 11g purge specific instances

You can delete specific instances via EM, but we wanted to delete it from database as we were facing issue on EM console batch delete mentioned here.

The OOTB purge process seems to be having some challenges:

DECLARE
  MIN_CREATION_DATE TIMESTAMP;
  MAX_CREATION_DATE TIMESTAMP;
  BATCH_SIZE NUMBER;
  MAX_RUNTIME NUMBER;
  RETENTION_PERIOD TIMESTAMP;
  PURGE_PARTITIONED_COMPONENT BOOLEAN;
  COMPOSITE_NAME VARCHAR2(200);
  COMPOSITE_REVISION VARCHAR2(200);
  SOA_PARTITION_NAME VARCHAR2(200);
BEGIN
  MIN_CREATION_DATE := systimestamp - 10000;
  MAX_CREATION_DATE := systimestamp;
  BATCH_SIZE := 20000;
  MAX_RUNTIME := 60;
  RETENTION_PERIOD := null;
  PURGE_PARTITIONED_COMPONENT := true;
  COMPOSITE_NAME := 'MyProcess';
  COMPOSITE_REVISION := '1.0';
  SOA_PARTITION_NAME := 'MyPartition';

  SOA.DELETE_INSTANCES(
    MIN_CREATION_DATE => MIN_CREATION_DATE,
    MAX_CREATION_DATE => MAX_CREATION_DATE,
    BATCH_SIZE => BATCH_SIZE,
    MAX_RUNTIME => MAX_RUNTIME,
    RETENTION_PERIOD => RETENTION_PERIOD,
    PURGE_PARTITIONED_COMPONENT => PURGE_PARTITIONED_COMPONENT,
    COMPOSITE_NAME => COMPOSITE_NAME,
    COMPOSITE_REVISION => COMPOSITE_REVISION,
    SOA_PARTITION_NAME => SOA_PARTITION_NAME
  );
--rollback; 
END;    

  • Procedure doesn't allow selective purge - e.g. I can not purge specific list of instance ids
  • Procedure runs pruning job which basically prevents purging faulted or running instances
Here is workaround :

  • Insert the ecid in ecid_purge table. Below is sample query, but select statement can be changed as you like.
truncate table ecid_purge;
insert into ecid_purge   select distinct ecid from composite_instance where composite_dn  like '%CustomerParty/SyncCustomerPartyListEBizProvABCSImpl!1.0%';  
commit; 

  • Run the following procedure to clean up the data. It will clean up faulted and open running instances as well
begin
  soa_orabpel.deleteComponentInstances('ecid_purge',true);
  soa_workflow.deleteComponentInstances('ecid_purge');
  soa_mediator.deleteComponentInstances('ecid_purge');
  soa_decision.deleteComponentInstances('ecid_purge');
  soa_fabric.deleteCompositeInstances('ecid_purge',true);
  commit;
end;


Thursday, September 5, 2013

Enable logging in purge process

I guess out of the box 11g SOA instance purge process kinda sucks, and majority of the time we end up customizing it for faster execution or just so that it is easy to read. However, time to time, I end up using OOTB purge process. We were trying to delete it from EM console and somehow just got hung and faced below error in logs.


Caused By: java.lang.NullPointerException
        at sym.productext.ui.bean.CreateDerivationHeaderBean.doDeleteRow(CreateDerivationHeaderBean.java:148)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at com.sun.el.parser.AstValue.invoke(AstValue.java:187)
        at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297)
        at org.apache.myfaces.trinidadinternal.taglib.util.MethodExpressionMethodBinding.invoke(MethodExpressionMethodBinding.java:53)
        at org.apache.myfaces.trinidad.component.UIXComponentBase.broadcastToMethodBinding(UIXComponentBase.java:1256)

So I had to try it from database. We ran following standard routine with standard parameters to delete all instances of specific composite, and the process completed in a few seconds - nothing got deleted and no error.

DECLARE
  MIN_CREATION_DATE TIMESTAMP;
  MAX_CREATION_DATE TIMESTAMP;
  BATCH_SIZE NUMBER;
  MAX_RUNTIME NUMBER;
  RETENTION_PERIOD TIMESTAMP;
  PURGE_PARTITIONED_COMPONENT BOOLEAN;
  COMPOSITE_NAME VARCHAR2(200);
  COMPOSITE_REVISION VARCHAR2(200);
  SOA_PARTITION_NAME VARCHAR2(200);
BEGIN
  MIN_CREATION_DATE := systimestamp - 10000;
  MAX_CREATION_DATE := systimestamp;
  BATCH_SIZE := 20000;
  MAX_RUNTIME := 60;
  RETENTION_PERIOD := null;
  PURGE_PARTITIONED_COMPONENT := true;
  COMPOSITE_NAME := 'MyProcess';
  COMPOSITE_REVISION := '1.0';
  SOA_PARTITION_NAME := 'MyPartition';

  SOA.DELETE_INSTANCES(
    MIN_CREATION_DATE => MIN_CREATION_DATE,
    MAX_CREATION_DATE => MAX_CREATION_DATE,
    BATCH_SIZE => BATCH_SIZE,
    MAX_RUNTIME => MAX_RUNTIME,
    RETENTION_PERIOD => RETENTION_PERIOD,
    PURGE_PARTITIONED_COMPONENT => PURGE_PARTITIONED_COMPONENT,
    COMPOSITE_NAME => COMPOSITE_NAME,
    COMPOSITE_REVISION => COMPOSITE_REVISION,
    SOA_PARTITION_NAME => SOA_PARTITION_NAME
  );
--rollback; 
END;                   



Upon looking further in PLSQL, found that it is using log_info and debug_purge to log the messages, but it will only be enabled if $$debug_on is there.

How to enable purge logging
ALTER PROCEDURE debug_purge  COMPILE PLSQL_CCFLAGS = 'debug_on:TRUE' REUSE SETTINGS;

ALTER PROCEDURE log_info COMPILE PLSQL_CCFLAGS = 'debug_on:TRUE' REUSE SETTINGS;


How to disable purge logging
ALTER PROCEDURE debug_purge COMPILE PLSQL_CCFLAGS = 'debug_on:false' REUSE SETTINGS;

ALTER PROCEDURE log_info COMPILE PLSQL_CCFLAGS = 'debug_on:false' REUSE SETTINGS;

The same can be found under $SOA_HOME/rcu/integration/soainfra/oracle/soa_purge/common/debug_on.sql and debug_off.sql.

It gives quite a bit of information on purge routine once it is enabled.