Showing posts with label OSB. Show all posts
Showing posts with label OSB. Show all posts

Sunday, October 25, 2015

OSB Cluster

Create a new Domain, using the "OSB Production" template
Create it in "Production" mode
Create MS osb_server1 and osb_server2 and put them into a cluster.

You will notice that this deployment:

"ALSB Cluster Singleton Marker Application" is targeted to osb_server1

wlsbJMSServer_auto_1 and 2 are targeted to osb_server1 and 2

WseeJmsServer_auto_1 and 2 are targeted to osb_server1 and 2

wli.reporting.purge.queue is deployed to wlsbJMSServer_auto_1

all the reporting, email file ftp sftp transport JMS queues are created as Distributed Destinations and targeted to the cluster
(wlsb.internal.transport.task.queue.ftp_auto_1, wlsb.internal.transport.task.queue.sftp_auto_1, wlsb.internal.transport.task.queue.email_auto_1, wlsb.internal.transport.task.queue.file_auto_1, QueueIn_auto_1, wli.reporting.jmsprovider.queue_auto_1, wli.reporting.jmsprovider_error.queue_auto_1)


DefaultCallbackQueue-WseeJmsServer_auto_1/2 and DefaultQueue-WseeJmsServer_auto_1/2 are deployed to either server



see here


for File, FTP, email:
"the poller on only one managed server will poll for a given proxy service"

Friday, November 7, 2014

SBConsoleAccessException

I had to start admin on a different machine, and I was getting

com.bea.alsb.console.common.base.SBConsoleAccessException: The current login role is not authorized to use the console action: "/sbSubModules"

The only way I managed to make it work is by replacing DOMAIN_HOME/servers/osbpp1ms2/data/ldap/ with the content of another server:

cd opt/oracle/domains/osbpp1do/servers/osbpp1as/data/
cp -R ldap/ ldapOLD/ 
cp -R /opt/oracle/domains/osbpp1do/servers/osbpp1ms2/data/ldap/* ldap/


Tuesday, September 23, 2014

OSB: extending a domain by adding extra Managed Servers

See Oracle document "WLST Script to Add a Managed Server to an Existing OSB Cluster (Doc ID 1450865.1)", the provide you a WLST script extendOSBDomain.py to do the job.

The script must:

  • Create the new MS and set its listen-address and port etc etc
  • Alter the cluster to add the new MS to the cluster address
  • Create the JMS resources ["FileStore", "WseeFileStore"] (filestore, Jmsserver), creating also the $DOMAIN_HOME/WseeFileStore_auto_* etc folders, the JMS module and queues ["wli.reporting.jmsprovider.queue", "wli.reporting.jmsprovider_error.queue", "wlsb.internal.transport.task.queue.email", "wlsb.internal.transport.task.queue.file", "wlsb.internal.transport.task.queue.ftp", "wlsb.internal.transport.task.queue.sftp","QueueIn"]
  • create a SAF agent


So, on the whole, the job is not as simple as "clone an existing MS". incidentally, cloning doesn't reproduce exactly all settings of the original MS, for instance, log properties like "RotateLogOnStartup" and "limit number and size" are NOT copied, nor are logfilters (and forget about filestores, JMS resources etc).

See also this doc about scaling up.

Wednesday, August 27, 2014

OSB and SLA alerts in Eclipse

When you define a SLA alert in the OSB Console (sbconsole) this xml is added you your .proxy file :
  <ser:alertRules>
    <ser:alertRule name="slow" enabled="true">
      <aler:description>slow</aler:description>
      <aler:AlertFrequency>every-time</aler:AlertFrequency>
      <aler:AlertSeverity>normal</aler:AlertSeverity>
      <aler:StopProcessing>false</aler:StopProcessing>
      <aler:Condition type="statistics">
        <aler:config aggregation-interval="10" xsi:type="mon:monitoringConditionType" xmlns:mon="http://www.bea.com/wli/monitoring/alert/condition/monitoringstatistic">
          <mon:monCondExpr>
            <mon:function>max</mon:function>
            <mon:lhs>Project$PVtest/PVtest/Transport/response-time</mon:lhs>
            <mon:lhs-operand-type xsi:nil="true"/>
            <mon:lhsDisplayName>Response Time</mon:lhsDisplayName>
            <mon:operator>></mon:operator>
            <mon:rhs>600000</mon:rhs>
          </mon:monCondExpr>
        </aler:config>
      </aler:Condition>
      <aler:AlertDestination ref="PVtest/pier"/>
      <aler:AlertSummary>slow</aler:AlertSummary>
    </ser:alertRule>
  </ser:alertRules>

where PVtest/pier is an AlertDestination.

The horrifying thing is that if I import into eclipse this sbconfig.jar, the alertRules is emptied.

You can find some reference in the comments here and here. Of course I am shocked and horrified, because this is horrible and horrific.

So if you want to have those SLA, you must be very careful with Eclipse....

Thursday, July 17, 2014

OSB and the Load Balancer Source-IP (X-Forwarded-For)

If you configure correctly the Load balancer, OSB should be able to retrieve the actual Client (Originator) IP address:

tran:user-header name="Source-IP" value="10.56.164.149"

   <inbound>
      <con:endpoint name="ProxyService$PVLoadBalancerTest$PVLoadBalancerTestPS" xmlns:con="http://www.bea.com/wli/sb/context">
         <con:service/>
         <con:transport>
            <con:uri>/PVLoadBalancerTest/PVLoadBalancerTestPS</con:uri>
            <con:mode>request-response</con:mode>
            <con:qualityOfService>best-effort</con:qualityOfService>
            <con:request xsi:type="http:HttpRequestMetaData" xmlns:http="http://www.bea.com/wli/sb/transports/http" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
               <tran:headers xsi:type="http:HttpRequestHeaders" xmlns:tran="http://www.bea.com/wli/sb/transports">
                  <tran:user-header name="Source-IP" value="10.56.164.149"/>
                  <http:Accept-Encoding>gzip,deflate</http:Accept-Encoding>
                  <http:Content-Length>0</http:Content-Length>
                  <http:Content-Type>application/xml</http:Content-Type>
                  <http:Host>myhost.acme.com</http:Host>
                  <http:User-Agent>Jakarta Commons-HttpClient/3.1</http:User-Agent>
               </tran:headers>
               <tran:encoding xmlns:tran="http://www.bea.com/wli/sb/transports">iso-8859-1</tran:encoding>
               <http:relative-URI>PVLoadBalancerTest/PVLoadBalancerTestPS</http:relative-URI>
               <http:client-host>10.56.15.34</http:client-host>
               <http:client-address>10.56.15.34</http:client-address>
               <http:http-method>POST</http:http-method>
            </con:request>
            <con:response xsi:type="http:HttpResponseMetaData" xmlns:http="http://www.bea.com/wli/sb/transports/http" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
               <tran:headers xsi:type="http:HttpResponseHeaders" xmlns:tran="http://www.bea.com/wli/sb/transports">
                  <http:Content-Type>text/xml</http:Content-Type>
               </tran:headers>
               <tran:response-code xmlns:tran="http://www.bea.com/wli/sb/transports">0</tran:response-code>
            </con:response>
         </con:transport>
         <con:security>
            <con:transportClient>
               <con:username><anonymous></con:username>
            </con:transportClient>
         </con:security>
      </con:endpoint>
   </inbound>





while the http:client-host and the http:client-address refer to the Load Balancer IP address (fixed)

How the LB should be configured, I have little clue, I only know that they do a "Insert Src IP Addr..: Header field : "Source-IP"". See here for instruction for a specific product Citrix NetScaler .

this XPath will extract the info :

$inbound/ctx:transport/ctx:request/tp:headers/tp:user-header[@name='Source-IP']

In order to log this IP in the WebLogic access.log file, see document "How to obtain the correct Client IP address when a Physical Load Balancer and a Web Server Configured With Proxy Plug-in Are Between The Client And Weblogic (Doc ID 1375129.1)", where they explain the "Insert XForwardedFor" , the "WL-Proxy-Client-IP" and the "WebLogic Plug-In Enabled".

See also http://en.wikipedia.org/wiki/X-Forwarded-For

From the Console Help of "WebLogic Plug-In Enabled" I read:

Set this attribute to true if the cluster will receive requests from a proxy plug-in or HttpClusterServlet. When WeblogicPluginEnabled is true, a call to getRemoteAddr will return the address of the browser client from the proprietary WL-Proxy-Client-IP header, instead of the web server.

So I believe that the name of the header should be changed from "Source-IP" to "WL-Proxy-Client-IP" in order to be able to capture it.... too bad it's not configurable... no, wait, the doc says "Since 10.3.3 it is possible to configure a specific header that WLS will check when getRemoteAddr is called. That can be set on the WebServer Mbean.". It looks like they refer to this method.

One should then choose HTTP Logging as ELF (Extended Logging Format), by default the fields are "date time cs-method cs-uri sc-status". One should add cs(X-Forwarded-For) or cs(Source-IP) or whatever name you are using for the header.



From the Oracle DOC 1375129.1:


1. At weblogic end, you need to enable the "WebLogic Plug-In Enabled" This option can be set both at the cluster level or server level.

WebLogic Plug-In Enabled:

Set this attribute to true if the cluster will receive requests from a proxy plug-in or HttpClusterServlet. When WeblogicPluginEnabled is true, a call to getRemoteAddr will return the address of the browser client from the proprietary WL-Proxy-Client-IP header, instead of the web server.

For non-clustered servers that will receive proxied requests, this attribute may be set at the server level, on the Server > Configuration >General tab.

If you want to set it at cluster level, ex: Home >Summary of Servers >Summary of Clusters >new_Cluster_1 > General > Advanced

2. At the loadbalancer end, you need to creating HTTP profile and then enable "WL-Proxy-Client-IP: [IP::client_addr]" ,  and also enable "Insert XForwardedFor"
 




Tuesday, July 8, 2014

OSB, Multipart Email and reading attachments in IPad

How to send an email with attachment in OSB is already covered elsewhere.

However there are some caveats: some email clients like IPad/IPhone are really picky, and they don't handle correctly a PDF in attachment if the OSB default is used.

Here it says: OSB when an attachment is present in the message, OSB is overrding the "Content-Type" property to "multipart/related" inspite of me setting the "Content-Type" property of HTTP Transport Header in OSB

The problem is that an IPad seems to handle correctly only messages with "Content-Type" = multipart/alternative or multipart/mixed. So the only choice is to manufacture yourself the $body message to send to the SMTP Mail Business Service, by hardcoding the multipart/alternative. By no means you should have Content-ID around: IPad doesn't like them.

This is done in an Oracle Support article : Service Bus 11g: How to Send a Multipart Email (Doc ID 1561677.1)

To import the project in a OSB version prior to 11.1.1.6, in ExportInfo, change : imp:property name="productversion" value="11.1.1.5" and rejar everything.

Refer to http://en.wikipedia.org/wiki/MIME for comprehensive explanation of MIME standards.

Gmail menu "show original" was essential to debug the actual email content.

See also this article where Apple support warns about possible issues with attachment... guys, how about testing better your code and make it more robust?

Also, always remember to delete $attachments variable before you route to BS !

One more thing: it seems that iOS changes the filename into filename="mime-attachment.pdf" for large PDF ( > 50 KB approximately). This is really really weird. no workaround so far. Not a HUGE issue, but still annoying. Actually this seems to happen only if there is a space in the filename...

Friday, June 27, 2014

SOA Suite 12c contains the "next generation" OSB

I am not going to blog over the new features of SOA Suite 12c, this is already taken care of by the excellent Jan

Installation http://jvzoggel.wordpress.com/2014/06/27/installing-oracle-soa-suite-12-1-3-for-developers/

Create Project http://jvzoggel.wordpress.com/2014/06/27/creating-a-new-oracle-service-bus-12c-project/

OSB Hello World http://jvzoggel.wordpress.com/2014/06/27/building-a-simple-oracle-service-bus-12c-helloworld-service/

Integrated WebLogic server http://jvzoggel.wordpress.com/2014/06/27/how-to-run-and-debug-oracle-service-bus-12c-services-on-the-integrated-weblogic-server/

Here starting from minute 4 you can actually see a living demo of OSB in Jdeveloper... the view is familiar to SOA Suite developer...




Anyway lot of information can be obtained on the official Oracle page


Also, quite useful this illustration of the new features and comparison with 11g

http://niallcblogs.blogspot.ch/2014/06/1-soa-12c-new-features-overview.html
http://niallcblogs.blogspot.ch/2014/06/2-soa12c-new-features-project-structure.html
http://niallcblogs.blogspot.ch/2014/06/4-soa-12c-new-features-osb-design-time.html

etc etc

and Maven support http://biemond.blogspot.ch/2014/06/maven-support-for-1213-service-bus-soa.html

and dependency visualization http://technology.amis.nl/2014/06/28/soa-suite-12c-exploring-dependencies-visualizing-dependencies-between-soa-artifacts/

and XQuery libraries http://technology.amis.nl/2014/06/28/soa-suite-12c-support-for-reusable-xquery-libraries-modules/



Securing OSB SOAP service with WS-Policy UsernameToken

Since we had some issue with OWSM and Attachments (solved in 11.1.1.7, but we are on 11.1.1.5) we decided to use some Predefined Web Service Security Policy.

The proxy has this WSDL :

<wsdl:definitions name="PVHelloWorld" 
targetNamespace="http://www.example.org/PVHelloWorld/" 
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.example.org/PVHelloWorld/" 
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
   xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">

  <wsdl:types>
 <xsd:schema>
  <xsd:import namespace="http://www.example.org/PVHelloWorld/" schemaLocation="PVHelloWorld.xsd"/>
 </xsd:schema>
  </wsdl:types>
  
  <wsdl:message name="HelloWorldRequest">
    <wsdl:part element="tns:HelloWorldRequest" name="parameters"/>
  </wsdl:message>
  
  <wsdl:message name="HelloWorldResponse">
    <wsdl:part element="tns:HelloWorldResponse" name="parameters"/>
  </wsdl:message>
  
  <wsdl:portType name="PVHelloWorldPortType">
    <wsdl:operation name="HelloWorld">

      <wsdl:input message="tns:HelloWorldRequest">

</wsdl:input>
      <wsdl:output message="tns:HelloWorldResponse"/>
    </wsdl:operation>
  </wsdl:portType>
  
  <wsdl:binding name="PVHelloWorldPortBinding" type="tns:PVHelloWorldPortType">

    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="HelloWorld">
      <soap:operation soapAction="http://www.example.org/PVHelloWorld/HelloWorld"/>
      <wsdl:input>
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  
  <wsdl:service name="PVHelloWorld">
    <wsdl:port binding="tns:PVHelloWorldPortBinding" name="PVHelloWorldPort">
      <soap:address location="http://www.example.org/"/>
    </wsdl:port>
  </wsdl:service>
  
</wsdl:definitions>



where the PVHelloWorld.xsd is:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
 targetNamespace="http://www.example.org/PVHelloWorld/" 
 xmlns:tns="http://www.example.org/PVHelloWorld/" 
 elementFormDefault="qualified">

    <element name="HelloWorldRequest" type="string"></element>

    <element name="HelloWorldResponse" type="string"></element>
    
</schema>


After you have to apply security to Request only.


If you apply Security to Operation, then it tries to apply security also to Response, and it fails:
####<Jun 27, 2014 10:23:40 AM CEST> <Error> <OSB Security> <acme102> <osbdev1ms1> <[ACTIVE] ExecuteThread: '10' for queue: 'weblogic.kernel.Default (self-tuning)'> <<anonymous>> <> <7f9b72b69446518a:670088d3:146d8a74ad2:-8000-0000000000004f16> <1403857420200> <BEA-387023> <An error ocurred during web service security inbound response processing [error-code: Fault, message-id: 6720812917736772435-670088d3.146d8a74ad2.-7882, proxy: PVSecurityTest/PVHelloWorld, operation: HelloWorld]
--- Error message:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"><env:Header/><env:Body><env:Fault><faultcode>env:Server</faultcode><faultstring>Unable to add security token for identity</faultstring></env:Fault></env:Body></env:Envelope>
weblogic.xml.crypto.wss.WSSecurityException: Unable to add security token for identity
        at weblogic.wsee.security.wss.SecurityPolicyDriver.doIdentity(SecurityPolicyDriver.java:193)
        at weblogic.wsee.security.wss.SecurityPolicyDriver.processIdentity(SecurityPolicyDriver.java:162)
        at weblogic.wsee.security.wss.SecurityPolicyDriver.processOutbound(SecurityPolicyDriver.java:74)
        at weblogic.wsee.security.wss.SecurityPolicyDriver.processOutbound(SecurityPolicyDriver.java:65)
        at weblogic.wsee.security.WssServerHandler.processOutbound(WssServerHandler.java:88)
        at weblogic.wsee.security.WssServerHandler.processResponse(WssServerHandler.java:70)
        at weblogic.wsee.security.WssHandler.handleResponse(WssHandler.java:127)
        at com.bea.wli.sb.security.wss.wls.Wls92InboundHandler.processResponse(Wls92InboundHandler.java:261)
        at com.bea.wli.sb.security.wss.WssHandlerImpl.doInboundResponse(WssHandlerImpl.java:918)
        at com.bea.wli.sb.context.BindingLayerImpl.createTransportReplySender(BindingLayerImpl.java:416)
        at com.bea.wli.sb.context.BindingLayerImpl.addResponse(BindingLayerImpl.java:506)
        at com.bea.wli.sb.pipeline.MessageProcessor.finishProcessing(MessageProcessor.java:349)
        at com.bea.wli.sb.pipeline.RouterCallback.onReceiveResponse(RouterCallback.java:108)
        at com.bea.wli.sb.pipeline.RouterCallback.run(RouterCallback.java:183)
        at weblogic.work.ContextWrap.run(ContextWrap.java:41)
        at weblogic.work.SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:528)
        at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
        at weblogic.work.ExecuteThread.run(ExecuteThread.java:178)
>




You must then customize the policy (by default, everyone can access):




and add the condition User = BLA (it's covered in red in the picture below)




The alternative is to embed policies in the WSDL:

This to be put only once:

<wsp:UsingPolicy wsdl:Required="true" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"/>

and this to be applied for each part you want to protect with Authorization:

<wsp:Policy> <wsp:PolicyReference URI="policy:Auth.xml"/> </wsp:Policy>

The curious thing is that if Request authentication fails, the service error handler is invoked:


 <con:fault xmlns:con="http://www.bea.com/wli/sb/context">
  <con:errorCode>BEA-386201</con:errorCode>
  <con:reason>A web service security fault occurred[{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}FailedAuthentication][Failed to assert identity with UsernameToken.]</con:reason>
  <con:details>
    <err:WebServiceSecurityFault xmlns:err="http://www.bea.com/wli/sb/errors">
      <err:faultcode xmlns:oas="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">oas:FailedAuthentication</err:faultcode>
      <err:faultstring>Failed to assert identity with UsernameToken.</err:faultstring>
    </err:WebServiceSecurityFault>
  </con:details>
  <con:location>
    <con:path>request-pipeline</con:path>
  </con:location>
</con:fault>






Oracle File Adapter Scalable DOM

I have tried to activate streaming parsing of an xml file with OSB:


this consists in replacing oracle.tip.adapter.file.inbound.FileActivationSpec with oracle.tip.adapter.file.inbound.ScalableFileActivationSpec, and enabling streaming parsing on the File poller Proxy Service. I also set MaxFileAge to 5, to avoid picking up a file before it's completely copied to the Input folder.

I put a SMALL (3 kb file) document 608-12.xml in the input folder, and I get:

Generic Error caught while translating inbound file  in streaming mode  : 608-12.xml
java.lang.NullPointerException
        at oracle.tip.adapter.file.inbound.InboundTranslatorDelegate.xlate(InboundTranslatorDelegate.java:295)
        at oracle.tip.adapter.file.inbound.InboundTranslatorDelegate.doXlate(InboundTranslatorDelegate.java:121)
        at oracle.tip.adapter.file.inbound.ProcessorDelegate.doXlate(ProcessorDelegate.java:388)
        at oracle.tip.adapter.file.inbound.ProcessorDelegate.process(ProcessorDelegate.java:174)
        at oracle.tip.adapter.file.inbound.ProcessWork.run(ProcessWork.java:349)
        at weblogic.work.ContextWrap.run(ContextWrap.java:41)
        at weblogic.work.SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:528)
        at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
        at weblogic.work.ExecuteThread.run(ExecuteThread.java:178)
>



According to Oracle Support KB, this should happen only for HUUUGE documents and in old versions of OSB (we use 11.1.1.5). Related thread on the forum, reporting the same issue, are unanswered.

I am afraid we shall not use this streaming option for the time being.

See also https://community.oracle.com/thread/2195895 (discussion archived without solution...)

Tuesday, June 24, 2014

Transformation from com.bea.wli.sb.sources.XmlObjectSource to com.bea.wli.sb.sources.MessageContextSource is not supported

in OSB, when using a SOAP with Attachment in a Proxy with OWSM Policies, you get this error message:

Transformation from com.bea.wli.sb.sources.XmlObjectSource to com.bea.wli.sb.sources.MessageContextSource is not supported

This is described in Oracle DOC "Combined use of SOAP with Attachments and OWSM Policies now Supported in OSB 11.1.1.7 (Doc ID 1347447.1)".

The solution is: upgrade to OSB 11.1.1.7. Or give up attachments. Or give up OWSM. Ok don't tell me I am stupid because I already know.

Tuesday, June 3, 2014

unpack of a OSB domain fails if OSB is not installed (of course...)

The unpack of a OSB domain template will fail with:

Required component home not found for component 'oracle.as.jrf' version '11.1.1.7.0'"

I think at the origin of the issue is that it's expecting to find the component home in this file:
/opt/oracle/middleware11g/Oracle_OSB1/inventory/ContentsXML/comps.xml

which of course is not available of OSB binaries are not installed.

One would have appreciated a message like "unable to proceed, OSB not installed", but no, life would be too boring of all was perfect clean and intuitive.



Wednesday, May 21, 2014

OSB versions: how to tell which version is installed

in the sbconsole, click on About Service Bus: OSB 11.1.1.5.0:
Oracle Service Bus 11.1 Wed Apr 20 04:25:20 EDT 2011 1400736. Oracle Service Bus 11gR1 Copyright © 2004, 2011
OSB 11.1.1.7.0:
Oracle Service Bus 11.1 Fri Mar 8 04:05:15 PST 2013 1514631. Oracle Service Bus 11gR1 Copyright © 2004, 2013



Monday, May 19, 2014

OSB, read file content as binary response from HTTP

The trick is:

  • Create a "Messaging Service" Business Service
  • Request type = None
  • Response type = Binary
  • HTTP method = GET


the GET method becomes available only when you choose "request type = None", otherwise you have only POST, PUT and DELETE.

This will return a binary-content response variable that you can process as a Java byte[].

Service Callout will not work with such a BS, because it's Request Type = None. If you try doing it, you get "A callout cannot invoke a one-way operation". Try rather Route.

Forcing a GET HTTP Method to a BS with "Request Type = String", you get this error message:

"[WliSbTransports:381333]HTTP method "GET" is only allowed for Service Type any xml or messaging type with none as the request type."

If you get NullPointerException, try applying Patch 12362492 - patching /opt/oracle/fmw11_1_1_5/osb/lib/sb-transports-main.jar - it worked for us.

Tuesday, April 15, 2014

osb_server1, where does it come from?

When you create a new OSB domain, typically you include 2 templates:

SB_BASE_TEMPLATE = '/common/templates/applications/wlsb_base.jar'
SB_TEMPLATE = '/common/templates/applications/wlsb.jar'

in wlsb.jar there is a tiny config.xml defining the osb_server1 managed server.

So, a brand new domain will contain this osb_server1.

To customize the domain, you can either delete it (not advisable, since there are singleton services targeted to it) or rename it (better this way)

In the same way, a datasource wlsbjmsrpDataSource will be created automatically, using some default values:

<jdbc-data-source xmlns="http://xmlns.oracle.com/weblogic/jdbc-data-source">
  <name>wlsbjmsrpDataSource</name>
  <jdbc-driver-params>
    <url>jdbc:derby://localhost:1527/osbexamples;create=true;serverName=localhost</url>
    <driver-name>org.apache.derby.jdbc.ClientDriver</driver-name>
    <properties>
      <property>
        <name>user</name>
        <value>DEV_SOAINFRA</value>
      </property>
    </properties>
    <password-encrypted>weblogic</password-encrypted>
  </jdbc-driver-params>
  <jdbc-connection-pool-params>
    <initial-capacity>5</initial-capacity>
    <max-capacity>20</max-capacity>
    <capacity-increment>1</capacity-increment>
  </jdbc-connection-pool-params>
  <jdbc-data-source-params>
    <jndi-name>wlsbjmsrpDataSource</jndi-name>
    <global-transactions-protocol>LoggingLastResource</global-transactions-protocol>
  </jdbc-data-source-params>
</jdbc-data-source>


Of course you will have to customize this Datasource to suit your needs, with code like this:
            DS_NAME_REP = 'wlsbjmsrpDataSource'
            db_driver = 'oracle.jdbc.OracleDriver'
            db_url = 'jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=myhost.acme.com)(PORT=1522))(CONNECT_DATA=(SERVICE_NAME=myservice)))'
            db_password = 'bla'
            db_name = 'myservice'

            cd('/')
            cd('JDBCSystemResource/' + DS_NAME_REP + '/JdbcResource/' + DS_NAME_REP )
            cd('JDBCDriverParams/NO_NAME_0')
            set('DriverName', db_driver)
            set('URL', db_url)
            set('PasswordEncrypted', db_password )
            
            # set/create all properties
            cd('Properties/NO_NAME_0')
            
            cd('Property/user')
            cmo.setValue(db_username)
            
            cd('../..')
            create('databaseName', 'Property')
            cd('Property/databaseName')
            cmo.setValue(db_name)
            
            cd('../..')
            create('serverName', 'Property')
            cd('Property/serverName')
            cmo.setValue(db_host)
            
            cd('../..')
            create('portNumber', 'Property')
            cd('Property/portNumber')
            cmo.setValue(db_port)
            
            cd('/JDBCSystemResource/' + DS_NAME_REP + '/JdbcResource/' + DS_NAME_REP )
            cd('JDBCConnectionPoolParams/NO_NAME_0')
            set('TestTableName', db_testtable)

            set('InitialCapacity', 0)
            
            cd('/JDBCSystemResource/' + DS_NAME_REP + '/JdbcResource/' + DS_NAME_REP )
            cd ('JDBCDataSourceParams/NO_NAME_0' )
            set('GlobalTransactionsProtocol', 'LoggingLastResource')
            


All this is very beautiful and instructive.

Thursday, February 27, 2014

Oracle JCA DbAdapter db poller at work

I can see 4 threads
"[ACTIVE] ExecuteThread: '24' for queue: 'weblogic.kernel.Default (self-tuning)'" waiting for lock oracle.tip.adapter.db.InboundWork@5adcf919 TIMED_WAITING

 java.lang.Object.wait(Native Method)

 oracle.tip.adapter.db.InboundWork.run(InboundWork.java:609)

 oracle.tip.adapter.db.inbound.InboundWorkWrapper.run(InboundWorkWrapper.java:43)

 weblogic.work.ContextWrap.run(ContextWrap.java:41)

 weblogic.work.SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:528)

 weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)

 weblogic.work.ExecuteThread.run(ExecuteThread.java:178)


and when it fails I see the full stack trace:
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:476)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:204)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:540)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:217)
at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1079)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1466)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3752)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3887)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1508)
at weblogic.jdbc.wrapper.PreparedStatement.executeUpdate(PreparedStatement.java:172)
at oracle.tip.adapter.db.inbound.DestructivePollingStrategy.poll(DestructivePollingStrategy.java:434)
at oracle.tip.adapter.db.InboundWork.runOnce(InboundWork.java:699)
at oracle.tip.adapter.db.InboundWork.run(InboundWork.java:578)
at oracle.tip.adapter.db.inbound.InboundWorkWrapper.run(InboundWorkWrapper.java:43)
at weblogic.work.ContextWrap.run(ContextWrap.java:41)
at weblogic.work.SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:528)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:178)


I note down the 4 threads name (12,13,14,24) and execute a poll on a record.
Why 4 threads? Because we have 4 Proxy Services using the oracle.tip.adapter.db.DBActivationSpec to poll a table, and each is configured in the JCA file with NumberOfThreads=1:
  <endpoint-activation portType="SSS_Batching_Service_ptt" operation="receive">
    <activation-spec className="oracle.tip.adapter.db.DBActivationSpec">
      <property name="DescriptorName" value="SSS_Batching_Service.SssBatchOrder"/>
      <property name="QueryName" value="SSS_Batching_ServiceSelect"/>
      <property name="MappingsMetaDataURL" value="NCube_Batching_Service-or-mappings.xml"/>
      <property name="PollingStrategy" value="LogicalDeletePollingStrategy"/>
      <property name="MarkReadColumn" value="STATUS"/>
      <property name="MarkReadValue" value="PROCESSED"/>
      <property name="MarkReservedValue" value="R${weblogic.Name-2}-${IP-2}"/>
      <property name="MarkUnreadValue" value="CREATED"/>
      <property name="PollingInterval" value="60"/>
      <property name="MaxRaiseSize" value="10"/>
      <property name="MaxTransactionSize" value="10"/>
      <property name="NumberOfThreads" value="1"/>
      <property name="ReturnSingleResultSet" value="false"/>
    </activation-spec>
  </endpoint-activation>


See here Polling Thread: By default, as a performance best practice, the Oracle Database Adapter uses one thread to poll the database (NumberOfThreads=1 property in the activation spec). Because the adapter never releases that thread, which is by design, you may see a stuck thread stack trace in the server log. If you set the NumberOfThreads to more than one, you may see stack traces for all of those threads. You can ignore stuck thread stack traces.

Analyzing the logs, it's evident that THE SAME POLLING THREAD IS USED IN OSB TO PROCESS THE MESSAGE.

We have an issue here: if the Processing Time for a batch is > the Polling Period, the Polling Period is not guaranteed.

Something else to explore is to understand the behaviour of the component if we set NumberOfThreads to something > 1.

Friday, February 21, 2014

OSB load balancing of JMS messages

Obviously, use Distributed queues.
In the Business Service creating the JMS message, enter a single URI which has the cluster address, like:
jms://host1.acme.com:8001,host2.acme.com:8001/jms.jndi.cf.MyCF/jms.jndi.dq.MyDQ

and in the jms.jndi.cf.MyCF, in the "Load Balance" tab, disable the checkbox "Server Affinity Enabled".

See also http://docs.oracle.com/cd/E28280_01/web.1111/e13814/jmstuning.htm#PERFM311



Thursday, February 20, 2014

OSB binary JMS messages

If someone sets the message type to "binary" for a JMS Business Service, this will generate BytesMessage rather than TextMessage. You might have performance reasons to do that. But it's a pain, because in the WebLogic console these messages will not be very readable.
If you want to process those messages with some Java utility, you can still get the content of the message this way:
Enumeration msgs = queueBrowser.getEnumeration();
while (msgs.hasMoreElements()) {
    Message tempMsg = (Message)msgs.nextElement();
    String msgContent = "";
    if (tempMsg instanceof BytesMessage) {
        weblogic.jms.common.BytesMessageImpl bm = (weblogic.jms.common.BytesMessageImpl)tempMsg;
        msgContent = new String(bm.getBodyBytes());
    }
    if (tempMsg instanceof TextMessage) {
        msgContent = ((TextMessage)tempMsg).getText();
    }

}

the method getBodyBytes() is not part of the BytesMessage interface, but it's very convenient...
I guess that the message body COULD be compressed, in that case you are screwed, you might try decompressMessageBody() before reading the body, not sure...


OSB processing of gz gzip files

Taking example from this post, I have developed this Java Callout class:
package com.acme.osb.utilities;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.zip.GZIPInputStream;

public class UnzipAndWriteToFile {
 public static String inputFileName = "c:\\pierre\\myfile.txt.gz";
 public static String outputFileName = "c:\\pierre\\myfile.txt";

 public static void main(String[] args) throws Exception {
  unzipGZIPFile(inputFileName, outputFileName);
 }

 /*
  * Read from a gz byte[] and writes to a file
  */
 public static String processBytes(byte[] data, String outputFile) throws Exception {
  ByteArrayInputStream bais = new ByteArrayInputStream(data);
  fromGZStreamToFile(outputFile, bais);
  return "OK";
 }

 /**
  * Read from a gz file and writes the unzipped content to another file
  * 
  * @param fileName
  * @param outputFile
  * @throws Exception
  */
 public static void unzipGZIPFile(String fileName, String outputFile) throws Exception {
  FileInputStream in = new FileInputStream(fileName);
  fromGZStreamToFile(outputFile, in);
 }

 /**
  * Persist a gz stream to a file
  * @param outputFile
  * @param in
  * @throws IOException
  * @throws FileNotFoundException
  */
 private static void fromGZStreamToFile(String outputFile, InputStream in) throws IOException, FileNotFoundException {
  GZIPInputStream gzip = new GZIPInputStream(in);
  BufferedReader br = new BufferedReader(new InputStreamReader(gzip));
  PrintWriter pw = new PrintWriter(outputFile);
  String line;
  while ((line = br.readLine()) != null) {
   pw.println(line);
  }
  br.close();
  pw.close();
 }
}


Our aim is to read a gz file from HTTP server and write it locally, before we further process it.
We do a Service Callout to a Business Service (response type is binary), and it returns us this response: <con:binary-content ref="cid:-34da800e:1442fd94091:-7fae" xmlns:con="http://www.bea.com/wli/sb/context"/> .
We can pass this variable as such to the "public static String processBytes(byte[] data, String outputFile)" function, as this variable represents a reference to an array of bytes which is the binary content of the gz file. processBYtes will persist the unzipped content to a give file (specify full path)


Wednesday, January 8, 2014

osb, logback, logstash, grok and elasticsearch, putting it all together

the Java class that I invoke with a custom XPath to trace events :
  • "interface" is like "service/operation"
  • "eventtype" is like "FileConsumed", "JMSMessageConsumed", "WSInvoked"
  • TechnicalMessageID and BusinessID are usinque identifiers for the request/payload
  • ServerName is the WebLogic managed server
  • Priority is P1... P5 in case of error
  • Payload is the actual request... it's traced only if level is "DEBUG"
  • Fault is the error description
package com.acme.osb.logging;

import org.apache.xmlbeans.XmlObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Used by OSB to report an Event
 * 
 * @author NNVernetPI
 * 
 */

public class MessageTrackerSLF4J {

 public static String logMessage(String technicalMessageid,
   String businessId, String eventType, String interfaceName,
   XmlObject payload) {

  Logger projectLogger = LoggerFactory.getLogger(interfaceName);

  if (projectLogger.isDebugEnabled()) {
   projectLogger.info(" ::InterfaceName:: {} ::EventType:: {} ::TechnicalMessageID:: {} ::BusinessID:: {} ::ServerName:: {} ::Priority:: {} ::Payload:: {} ::Fault:: {}", 
     interfaceName, eventType, technicalMessageid, businessId, System.getProperty("weblogic.Name"), "NONE", payload != null ? payload.xmlText().replaceAll("\\r\\n|\\r|\\n", " ") : "NONE", "NONE");

  } else {
   projectLogger.info(" ::InterfaceName:: {} ::EventType:: {} ::TechnicalMessageID:: {} ::BusinessID:: {} ::ServerName:: {} ::Priority:: {} ::Payload:: {} ::Fault:: {}", 
     interfaceName, eventType, technicalMessageid, businessId, System.getProperty("weblogic.Name"), "NONE", "NONE", "NONE");
  }

  String logmessage = "Info Message Logged for:: " + interfaceName;
  return logmessage;
 }

 public static String errorLogger(String technicalMessageid,
   String businessId, String interfaceName, XmlObject payload,
   String priority, XmlObject fault) {

  Logger projectLogger = LoggerFactory.getLogger(interfaceName);

  projectLogger.error(" ::InterfaceName:: {} ::EventType:: {} ::TechnicalMessageID:: {} ::BusinessID:: {} ::ServerName:: {} ::Priority:: {} ::Payload:: {} ::Fault:: {}", 
    interfaceName, "ERROR", technicalMessageid, businessId, System.getProperty("weblogic.Name"), priority, payload != null ? payload.xmlText().replaceAll("\\r\\n|\\r|\\n", " ") : "NONE", fault != null ? fault.xmlText().replaceAll("\\r\\n|\\r|\\n", " ") : "NONE");

  String responseMessage = "Error Message Logged for:: " + interfaceName;
  return responseMessage;
 }

}



To make my parsing easier, I have decided to remove all newlines from payload and fault, so as to have a single line per event in the logs.

You can also deal with multiline with this codec.

For a valid message, logback will log:
#### 2014-01-08 18:04:01,980 INFO [[ACTIVE] ExecuteThread: '3' for queue: 'weblogic.kernel.Default (self-tuning)'] - ::InterfaceName:: ProdDeclAven ::EventType:: FileConsumed ::TechnicalMessageID:: ProdDeclAven^BAD_TST_PDA_REV.xml^AVE^1389200641480 ::BusinessID:: 000000000006741320_00376401092900001530 ::ServerName:: osbdev1ms1 ::Priority:: NONE ::Payload:: NONE ::Fault:: NONE ####

logback.xml file:
<?xml version="1.0" ?>
<configuration debug="true" scan="true" scanPeriod="30 seconds">
 <jmxConfigurator/>
 <property name="LOG_DIR" value="/opt/var/log/weblogic/server/"/>
 <appender class="ch.qos.logback.core.ConsoleAppender" name="STDOUT">
  <encoder>
   <pattern>
    #### %date{ISO8601} %level [%thread] - %msg ####%n            
   </pattern>
  </encoder>
 </appender>
 <appender class="ch.qos.logback.core.rolling.RollingFileAppender" name="MyService">
  <file>
   ${LOG_DIR}acmeMyService.log
  </file>
  <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
   <fileNamePattern>
    acmeMyService.%i.log.zip
   </fileNamePattern>
   <minIndex>
    1
   </minIndex>
   <maxIndex>
    10
   </maxIndex>
  </rollingPolicy>
  <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
   <maxFileSize>
    50MB
   </maxFileSize>
  </triggeringPolicy>
  <encoder>
   <pattern>
    #### %date{ISO8601} %level [%thread] - %msg ####%n                
   </pattern>
  </encoder>
 </appender>

 <logger additivity="false" level="INFO" name="MyService_PSDB_RoutingService">
  <appender-ref ref="MyService"/>
 </logger>

 <root level="DEBUG">
  <appender-ref ref="ALL"/>
 </root>
</configuration>





esgrok.conf will be

input {
  file {
    path => "/opt/var/log/weblogic/server/nesoa2*.log"
  }

}
filter {
  grok {
    match => [ "message", "#### %{TIMESTAMP_ISO8601:timestamp} %{WORD:level} \[\[%{WORD:threadstatus}\] %{GREEDYDATA:threadname}\] -  ::InterfaceName:: %{WORD:interfacename} ::EventType:: %{WORD:eventtype} ::TechnicalMessageID:: %{GREEDYDATA:technicalmessageid} ::BusinessID:: %{GREEDYDATA:businessid} ::ServerName:: %{WORD:servername} ::Priority:: %{WORD:priority} ::Payload:: %{GREEDYDATA:payload} ::Fault:: %{GREEDYDATA:fault} ####" ]
  }
}

output {
  elasticsearch {
    embedded => true
  }
}



Preparing the grok match regexp was very time consuming. Using http://grokdebug.herokuapp.com/ the grok debugger was essential. It worked for me only on Chrome, not on Firefox.

Priceless also the list of grok patterns.

Run with nohup java -jar logstash-1.3.2-flatjar.jar agent -f esgrok.conf -- web > logstash.log 2>&1 &
The result is impressive.
Happy Kibana to you!


Monday, December 30, 2013

OSB, WebLogic and Logback / SLF4j

Being totally fed up with the OSB reporting provider, I am setting up logback.
Maven:
<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-core</artifactId>
  <version>1.0.13</version>
</dependency>
<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>1.0.13</version>
</dependency>
             
<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-parent</artifactId>
  <version>1.0.13</version>
  <type>pom</type>
</dependency>
 
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.5</version>
</dependency>



vi /opt/oracle/fmw11_1_1_5/wlserver_10.3/common/bin/commEnv.sh

add this to WEBLOGIC_CLASSPATH:

${CLASSPATHSEP}/opt/oracle/fmw11_1_1_5/wlserver_10.3/server/lib/slf4j-api-1.7.5.jar${CLASSPATHSEP}/opt/oracle/fmw11_1_1_5/wlserver_10.3/server/lib/logback-core-1.0.13.jar${CLASSPATHSEP}/opt/oracle/fmw11_1_1_5/wlserver_10.3/server/lib/logback-classic-1.0.13.jar

and copy the JARs:

cd /opt/oracle/fmw11_1_1_5/wlserver_10.3/server/lib/

this only if you have Nexus, otherwise.... copy them manually:

wget http://nexus.nespresso.com/service/local/repositories/adobe-ext/content/ch/qos/logback/logback-core/1.0.13/logback-core-1.0.13.jar

wget http://nexus.nespresso.com/service/local/repositories/adobe-ext/content/ch/qos/logback/logback-classic/1.0.13/logback-classic-1.0.13.jar

wget http://nexus.nespresso.com/service/local/repositories/adobe-ext/content/org/slf4j/slf4j-api/1.7.5/slf4j-api-1.7.5.jar

vi /opt/oracle/domains/osbpl1do/config/osb/logback.xml

<configuration debug="true" scan="true" scanPeriod="30 seconds">
    <jmxConfigurator />
 
    <property name="LOG_DIR" value="/opt/var/log/weblogic/server/" />
 
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder
            by default -->
        <encoder>
            <pattern>%d %-5level [%thread] %logger{36} - %msg%n
            </pattern>
        </encoder>
    </appender>
 
    <appender name="GM"
        class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_DIR}GM.log</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
              <fileNamePattern>GM.%i.log.zip</fileNamePattern>
              <minIndex>1</minIndex>
              <maxIndex>10</maxIndex>
            </rollingPolicy>
            <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
              <maxFileSize>50MB</maxFileSize>
            </triggeringPolicy>
            <encoder>
                <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
                </pattern>
            </encoder>
    </appender>
 
 
    <logger name="POC_LOG4j" additivity="false" level="INFO">
        <appender-ref ref="GM" />
    </logger>
 
    <root level="DEBUG">
        <appender-ref ref="STDOUT" />
    </root>
 
 
</configuration>


I provide a custom XPath to log :
package com.acme.osb.logging;
import org.apache.xmlbeans.XmlObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * Used by OSB to report an Event
 *
 * @author NNVernetPI
 *
 */
public class MessageTrackerSLF4J {
    public static String logMessage(String technicalMessageid,
            String businessId, String eventType, String interfaceName,
            XmlObject payload) {
        Logger projectLogger = LoggerFactory.getLogger(interfaceName);
        StringBuilder sb = new StringBuilder();
        if (projectLogger.isDebugEnabled()) {
            sb.append(" ::InterfaceName::  ").append(interfaceName)
                    .append(" ::Payload:: ").append(payload.xmlText())
                    .append(" ::BusinessID::  ").append(businessId);
        } else {
            sb.append(" ::TechnicalMessageID::  ").append(technicalMessageid)
                    .append(" ::BusinessID::  ").append(businessId)
                    .append(" ::InterfaceName::  ").append(interfaceName)
                    .append(" ::EventType::  ").append(eventType)
                    .append(" ::ServerName:: ")
                    .append(System.getProperty("weblogic.Name"));
        }
        projectLogger.info(sb.toString());
        String logmessage = "Info Message Logged for:: " + interfaceName;
        return logmessage;
    }
    public static String errorLogger(String technicalMessageid,
            String businessId, String interfaceName, XmlObject payload,
            String priority, XmlObject fault) {
        Logger projectLogger = LoggerFactory.getLogger(interfaceName);
        StringBuilder sb = new StringBuilder();
        sb.append("::TechnicalMessageID::  ").append(technicalMessageid)
                .append("  ::InterfaceName::  ").append(interfaceName)
                .append("  ::BusinessID::  ").append(businessId)
                .append(" ::Payload:: ").append(payload.xmlText())
                .append(" ::Priority::  ").append(priority)
                .append(" ::FaultDescription:: ").append(fault.xmlText())
                .append(" ::ServerName:: ")
                .append(System.getProperty("weblogic.Name"));
        projectLogger.error(sb.toString());
        String responseMessage = "Error Message Logged for:: " + interfaceName;
        return responseMessage;
    }
}


which I expose as XPath this way:
  <xpf:function>
            <xpf:name>LOG_SLF_errorLogger</xpf:name>
            <xpf:comment>logs an error</xpf:comment>
            <xpf:namespaceURI>http://www.acme.com/acme2/xquery/xquery-functions</xpf:namespaceURI>
            <xpf:className>com.acme.osb.logging.MessageTrackerSLF4J</xpf:className>
            <xpf:method>java.lang.String errorLogger(java.lang.String, java.lang.String, java.lang.String, org.apache.xmlbeans.XmlObject, java.lang.String, org.apache.xmlbeans.XmlObject)</xpf:method>
            <xpf:isDeterministic>false</xpf:isDeterministic>
            <xpf:scope>Pipeline</xpf:scope>
            <xpf:scope>SplitJoin</xpf:scope>
        </xpf:function>     
        
  <xpf:function>
            <xpf:name>LOG_SLF_messageTracker</xpf:name>
            <xpf:comment>logs an event</xpf:comment>
            <xpf:namespaceURI>http://www.acme.com/acme2/xquery/xquery-functions</xpf:namespaceURI>
            <xpf:className>com.acme.osb.logging.MessageTrackerSLF4J</xpf:className>
            <xpf:method>java.lang.String logMessage(java.lang.String, java.lang.String, java.lang.String, java.lang.String, org.apache.xmlbeans.XmlObject)</xpf:method>
            <xpf:isDeterministic>false</xpf:isDeterministic>
            <xpf:scope>Pipeline</xpf:scope>
            <xpf:scope>SplitJoin</xpf:scope>
        </xpf:function>        


Since I have activated the jmxConfigurator, I can reload the logback.xml configuration file by connecting with JMX:

jconsole -J-Djava.class.path=C:\Oracle\MIDDLE~1\JDK160~1\lib\jconsole.jar;C:\Oracle\MIDDLE~1\JDK160~1\lib\tools.jar;C:\Oracle\Middleware\wlserver_10.3\server\lib\wlfullclient.jar -J-Djmx.remote.protocol.provider.pkgs=weblogic.management.remote -debug
and connect as:
service:jmx:iiop://myserver.acme.com:8001/jndi/weblogic.management.mbeanservers.runtime



The advantage is that I can also set programmatically the logger level for each logger, via JMX.



see here the doc, the first argument is the loggerName, the second is the level

A note: reloadByFileName() requires the FULL PATH : /opt/oracle/domains/osbpl1do/config/osb/logback.xml