Saturday, November 26, 2011

OSB custom reporting provider

Here an example:
http://www.oracle.com/technetwork/middleware/service-bus/learnmore/index.html

download link:
http://java.net/projects/oracleservicebus1031/downloads/download/SAMPLE-REPORTPROVIDER.zip


Here an interesting presentation http://www.slideshare.net/guest6070853/osb-bam-integration

In a nutshell this is what I understand:

a Reporting Provider should implement a com.bea.wli.reporting.ReportingDataHandler

public interface ReportingDataHandler
{

    public abstract void handle(XmlObject xmlobject, String s)
        throws Exception;

    public abstract void handle(XmlObject xmlobject, InputStream inputstream)
        throws Exception;

    public abstract void handle(XmlObject xmlobject, XmlObject xmlobject1)
        throws Exception;

    public abstract void handle(XmlObject xmlobject, XmlTokenSource xmltokensource)
        throws Exception;

    public abstract void handle(XmlObject xmlobject, Serializable serializable)
        throws Exception;

    public abstract void close();

    public abstract void flush();
}



apparently you only need to implement 3 handle methods:
handle( XmlObject metadata, String str )
void handle( XmlObject metadata, InputStream is )
handle( XmlObject metadata, XmlObject data )

and close() and flush()

(see the CustomReportDataFileProvider associated with the ZIP file above)


The implementation seems quite straightforward.



The OOTB JMS Report Provider uses a
com.bea.wli.reporting.jmsprovider.init.JmsReportingDataHandler implementation,
which uses wli.reporting.jmsprovider.ConnectionFactory and wli.reporting.jmsprovider.queue

Interestingly, the JmsReportingDataHandler suspends the Transaction if there is a non-XA transaction in course.


For the OOTB JMS Reporting provider:

if the Proxy Service where you use the Report action has "Transaction Required" = true, and the Tx fails (reply with error, or no reply), then the Report JMS message will not be produced.

if the Proxy Service where you use the Report action has "Transaction Required" = false, the Report JMS message will be produced no matter what.
See also http://jvzoggel.wordpress.com/2012/02/15/oracle-service-bus-logging-tracing-iii-create-custom-report-provider/ and http://docs.oracle.com/cd/E21764_01/doc.1111/e15867/reporting.htm and http://biemond.blogspot.ch/2013/06/custom-osb-reporting-provider.html
The classes involved in persisting the data in the WLI tables are:
com\bea\wli\reporting\jmsprovider\runtime\MDBMessageReporting
com\bea\wli\reporting\jmsprovider\runtime\ReportingDataAccessImpl
com\bea\wli\reporting\jmsprovider\utils\StatementFactory




Friday, November 25, 2011

OSB and JMS message acknowledgement

I am torturing myself over this problem:

I have a JMS message that I want to FTP:


JMSQUEUE -> JMS_PS (validation, tranformation) -> FTP_BS

If FTP_BS fails, I want to retry (redeliver) the message later

If the validation/transformation fail, I don't want to retry the message.

In both cases, I want to fail the transaction, so that the appropriate statistics are shown at monitoring level.

It turns out that you cannot acknowledge a JMS message in OSB independently from the result of the transaction. Here it says: OSB proxies always work in AUTO_ACKNOWLEDGE mode:
Tx rollback - > JMS message NOT ack'ed
Tx commit - > JMS message ack'ed


So, if you want to consume immediately the JMS message without retries, your only option is to "Reply with Success" in the error handler.

If the fault happened in the FTP_BS, at monitoring level (Operations/Service Health) you will find the error reported.
If the fault happened in the JMS_PS and you replied with success, the error will not appear in the Monitoring page.

A possible workaround could be:
never redeliver the JMS message, always acknowledge it, and upon FTP failure send the message to a RedeliveryQueue, from which it will be resubmitted in future (WebLogic supports delivery in future) to the main JMSQUEUE. Obviously this sucks.

Another workaround is to introduce a second JMSQUEUE2:
JMSQUEUE -> JMS_PS (validation, tranformation) -> JMSQUEUE2 -> FTP_BS

so that you separate validation/transformation from the FTPing.
This also sucks.

I cannot think of any other workaround.

Obviously this is not ideal, I hate committing a transaction when in reality we had a validation error, only for the sake of consuming immediately the JMS message.
I wish we had more control on the JMS message.

Redelivery at FTP_BS level (retries) is not an option, because they will keep a transaction open for a long time.

Wednesday, November 23, 2011

Error FTPing with JCA FTP Adapter


BEA-381971


Invoke JCA outbound service failed with connection error, exception: com.bea.wli.sb.transports.jca.JCATransportException: oracle.tip.adapter.sa.api.JCABindingException: oracle.tip.adapter.sa.impl.fw.ext.org.collaxa.thirdparty.apache.wsif.WSIFException: servicebus:/WSDL/ACME_PurchaseOrder/PV_FtpToACME [ Put_ptt::Put(body) ] - WSIF JCA Execute of operation 'Put' failed due to: Error in establishing connection to FTP Server.
Error in establishing connection to FTP Server.
Unable to establish connection to server.
; nested exception is:
BINDING.JCA-11438
Error in establishing connection to FTP Server.
Error in establishing connection to FTP Server.
Unable to establish connection to server.
Please ensure hostname and port specified to login to the server is correct.



The FTP Put is done in a Local Transaction:

in the log you will find:

JCA_FRAMEWORK_AND_ADAPTER Starting JCA LocalTransaction

and when the error occurs:

JCA_FRAMEWORK_AND_ADAPTER Rolling back JCA LocalTransaction

For the NoTransConnEventListener of pool 'eis/Ftp/ACMEFtpAdapter' CONNECTION_CLOSED event received

servicebus:/WSDL/ACME_PurchaseOrder/PV_FtpToACME [ Put_ptt::Put(body) ] - Marking this exception as Locally Retryable

WSIFCache: Closing CCI Connection

In fact the JCA Adapter for File and FTP do not support XA Transaction, but only Local Transactions.


The message is retried the number of times determined by the Business Service generated on top of the JCA Adapter:

Transport Configuration
Protocol jca
Load Balancing Algorithm round-robin
Endpoint URI
jca://eis/Ftp/ACMEFtpAdapter
Retry Count 2
Retry Iteration Interval 30
Retry Application Errors No

So in this case the message will be tried 3 times (2 retries) before erroring out. The local transaction only is retried, while the global transaction is still active. This makes the global transaction last 60 seconds.

Be aware that these local transactions are executed as part of the Proxy Service transaction: if you define 10 retries at 1 minute interval, your global transaction will be open for 10 minutes. So this is not a viable solution.

This is what you will see at the end of the TX:

<BEA-010213> <Message-Driven EJB: RequestEJB-7263521924761754948--49bf0c34.133cb4ae47d.-7fe0's transaction was rolled back. The transaction details are: Xid=BEA1-01DB458350C2A589D5FB(10150583),Status=Rolled back. [Reason=weblogic.transaction.internal.AppSetRollbackOnlyException: setRollbackOnly called on transaction],numRepliesOwedMe=0,numRepliesOwedOthers=0,seconds since begin=306,seconds left=60,XAServerResourceInfo[WLStore_prod_domain_FileStore_auto_1]=(ServerResourceInfo[WLStore_prod_domain_FileStore_auto_1]=(state=rolledback,assigned=osb_server1),xar=WLStore_prod_domain_FileStore_auto_121108363,re-Registered = false),SCInfo[prod_domain+osb_server1]=(state=rolledback),OwnerTransactionManager=ServerTM[ServerCoordinatorDescriptor=(CoordinatorURL=osb_server1+pierrepc:7011+prod_domain+t3+, XAResources={eis/tibjms/Topic, WLStore_prod_domain_FileStore_auto_1, eis/aqjms/Queue, eis/fioranomq/Topic, eis/wls/Queue, eis/tibjms/Queue, eis/activemq/Queue, WLStore_prod_domain_ACMEFileStore1, eis/pramati/Queue, WLStore_prod_domain__WLS_osb_server1, eis/tibjmsDirect/Queue, eis/Apps/Apps, eis/jbossmq/Queue, eis/sunmq/Queue, WSATGatewayRM_osb_server1_prod_domain, eis/aqjms/Topic, eis/tibjmsDirect/Topic, eis/wls/Topic, eis/AQ/aqSample, wlsbjmsrpDataSource_prod_domain, eis/webspheremq/Queue, WLStore_prod_domain_WseeFileStore_auto_1},NonXAResources={})],CoordinatorURL=osb_server1+pierrepc:7011+prod_domain+t3+).>


Go to the Server/MOnitoring/JTA/Transaction tab and you will see the transaction open for the entire duration of the retries. The transactionId is also traced in the logs.

We were consuming the message from a JMS queue, and redirecting on error to an ErrorQueue.

Poll results: what do I enjoy the most?



this reveals that most voters of this poll are socially oriented and curious about new stuff. cool, I like that.

I don't expect many politicians to have participated to this poll, otherwise the results would have been very different.

Tuesday, November 22, 2011

Reply with failure and the JCA Adapter

In a fault handler, we decide to fail the Transaction by using the "Reply with failure" Action.

For HTTP Proxy Services, this returns a HTTP 500 error code to the caller. For JMS, it will set the JMS_BEA_Error to true.

For JCA File Adapter Proxy Services, this mechanism doesn't work. The adapter doesn't receive the information that the Transaction failed (even if I set the Proxy as "Transaction required" and "Same Transaction for Response"). The file is archived and not sent to the Error directory.

The funny thing is that I have enabled all the debug flags for weblogic.jca , plus all the alsbdebug.xml flags... and it shows clearly that the isFailure=true, the message "OSB is rolling back a transaction BEA1-xxxx started by it", YET the AlsbJcaFrameworkAdapter says "successfully sent message to Adapter Framework".

If you want the Transaction to fail, the only way is to "Raise Error" in the Error Handler - or simply don't "Reply" at all.

Probably this (weird) behaviour will be addressed in future. JCA in OSB was introduced recently. IMHO the current behavious quite counter-intuitive.

BEA-000386 LDAP file (maybe) corrupted

We had some OutOfMemory errors in our server, and finally - after fixing the memory problems - we were unable to start the Admin because of this problem:

####<Nov 21, 2011 1:12:20 PM CET> <Critical> <WebLogicServer> <hqchnesoa102> <osbdv1as> <main> <<WLS Kernel>> <> <> <1321877540974> <BEA-000386> <Server subsystem failed. Reason: java.lang.NumberFormatException: null
java.lang.NumberFormatException: null
at java.lang.Integer.parseInt(Integer.java:417)
at java.lang.Integer.<init>(Integer.java:660)
at com.octetstring.vde.replication.Replication.initAgreements(Replication.java:146)
at com.octetstring.vde.replication.Replication.init(Replication.java:87)
at weblogic.ldap.EmbeddedLDAP.initReplication(EmbeddedLDAP.java:1304)
at weblogic.ldap.EmbeddedLDAP.start(EmbeddedLDAP.java:344)
at weblogic.t3.srvr.SubsystemRequest.run(SubsystemRequest.java:64)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:178)
>


moving the AdminServer/data/LDAP directory to a LDAP_BACKUP and restarting the server solved the problem. Of course we lost all the users.

I assume that the LDIF files simply get occasionally corrupted upon OOM. This is quite annoying.

Further digging showed that the file $DOMAIN_HOME/servers/AdminServer/data/ldap/conf/replicas.prop was empty, while it should contain something like this:


#Generated property file
#Mon Nov 21 13:38:21 CET 2011
replica.num=1
replica.0.name=osbdv1ms1
replica.0.base=dc\=osbdv1do
replica.0.port=8001
replica.0.hostname=soa102.acme.com
replica.0.masterurl=ldap\://soa102.acme.com\:7001/
replica.0.masterid=osbdv1as
replica.0.secure=0
replica.0.binddn=cn\=Admin
replica.0.consumerid=osbdv1ms1


How the file managed to get nuked, it's anybody's guess.

The message is: keep a backup of the AdminServer/data directory...

Monday, November 21, 2011

Version Information attached to a OSB Service/Project

If your customer he asks you "which version of a given service to we have in the TST environment?" you want to give him a 100% safe answer.

So you better find a way to return this info in a API.

Here is a way:

in each project (say POCVersioning), write a GetVersion proxy service:

Request Message Type = None
Response Message Type = XML

Replace [ node contents ] of [ . ] in [ body ] with XQuery Resource version

where "version" is a XQuery function like this:

<version>37</version>

At this point you can invoke from the browser

http://localhost:7011/POCVersioning/GetVersion

and you get back the <version>37</version> XML

Sounds silly? Maybe, but it saves a lot of trouble.

Of course, you want to assign automatically the version number in the automated build process (Hudson, Bamboo...) using some Maven/Ant/whatever versioning mechanism. Or just maintain it manually.

Sunday, November 20, 2011

What is new in Oracle WebLogic 12c?

so, what is new in weblogic 12c?

you can watch the recorded presentation join the launching webcast, I have managed to register only after giving up on my UK ZIP address and adopting a numbers-only one... tell me about US-centricity...


try also this link

and this link for the developer's cut

Here a detailed list of the new features.

In a nutshell:

* Java7 and JEE 6
* Oracle Traffic Director (Traffic Management)
* Much higher performance
* Integration with Oracle Public Cloud
* Integration with Oracle RAC
* TLS 1.2 (Transport Layer Security) support
* Much more compact code is required
* Oracle Virtual Assembly Builder for flexible Cloud configuration
* OEPE is still there
* Netbeans is there
* Maven easily builds WL12c artifacts
* "Light" WebLogic without EJB/JMS containers
* Fast Swap improved (hot redeploy of classes)
* Lightweight version to download (168 MB)

* More support for Dependency Injection

here the slides:



Friday, November 18, 2011

Move operation in JCA FTP Adapter

the UseNativeRenameOperation seems promising to do a Move (RNFR/RNTO) operation:

http://download.oracle.com/docs/cd/E12839_01/integration.1111/e10231/adptr_file.htm


but I haven't tested it yet...

Wednesday, November 16, 2011

OSB and rejectedMessageHandlers in JCA File Adapter

I am completing a previous post on the same topic.

By default, the JCA File Adapter will write bad files into $DOMAIN_HOME/jca/Read/rejectedMessages, renaming them to a filename like:

INVALID_MSG_154330703_Read_20111109_103658_0898.dat


If you specify in your JCA file the property PhysicalErrorArchiveDirectory=/path/to/my/errorDirectory, the bad files will be written here and not to the $DOMAIN_HOME/jca/Read/rejectedMessages directory.



To retry a "failed" file (only those who are not directly rejected by the Adapter, but for instance those who fail validation in the Proxy Service), you can specify in the JCA Transport Configuration of the Proxy Service:

jca.retry.count = "3"
jca.retry.interval = "40"


If you want to change the destination, there is a property rejectedMessageHandlers to be set (see oracle.tip.adapter.file. package). In SOA Suite you would set it in bpel.xml, in OSB it's a bit tricky:

edit the JCA Proxy Service, JCA Transport Configuration, Dynamic EndPoint Properties, add "rejectedMessageHandlers" with value "file://path/to/your/dir"


If you fail format, you will get this message:

Error JCA_FRAMEWORK_AND_ADAPTER BEA-000000 Unrecognized Rejection handler
Unrecognized Rejection handler
The Rejection handler C:/acme/po/rejected is not recognized.
Please use on of the existing Rejection handlers: file://, queue://, bpel:// or wsif://


so your options are a AQ queue (queue refers to AQ, not to JMS!), a BPEL process, a Web Service.



Here you have a series of possible formats for the destination:

http://download.oracle.com/docs/cd/B14099_19/integrate.1012/b14058/life_cycle.htm

it says that you can send the file to a JMS queue or a DB, not necessarily to a Directory... I haven't tested this.


Here the Oracle Integration File Adapter Datasheet , but it doesn't say much about error handler.

Monday, November 14, 2011

opaq:opaqueElement and base64Binary

If you want to write binary data to a FTP in OSB (or simply you want to avoid any nXSD transformation in your XML), you have the option of using

opaq:opaqueElement

You should in this case base64-encode your payload.
The bad news is that in Xquery 1.0 there is not a function to base64encode

You can do a Java Callout or a Custom XPath to a Java function.

There are plenty of BASE64Encoder classes around... from the BEA WLI framework, from Sun, from Apache....

In fact, Sun implementation
http://stackoverflow.com/questions/5549464/import-sun-misc-base64encoder-got-error-in-eclipse is not really an option.

We have identified the Apache Commons base64 encoder - in alternative to Sun implementation, since Sun (Oracle) itself recommends NOT to use sun packages http://www.oracle.com/technetwork/java/faq-sun-packages-142232.html - as the most commonly used encoder.


So, use this http://commons.apache.org/codec/ commons-codec-1.4.jar

Security and Authentication in JCA FTP File Adapter

I have setup a Credential Mapping to be able to do a Opaque FTP Put with the JCA FTP Adapter, as documented here

It maps a WebLogic user into a FTP EIS User.

I still get an authentication error:



####<13-Nov-2011 22:26:29 o'clock CET> <Error> <WliSbTransports> <pierrepc> <osb_server1> <[ACTIVE] ExecuteThread: '17' for queue: 'weblogic.kernel.Default (self-tuning)'> <<anonymous>> <BEA1-07F5BFB39FA8A589D5FB> <9218d6466d04a9d6:4f7d3afe:1339e75d3c7:-8000-00000000000000e4> <1321219589928> <BEA-381502> <Exception in JmsInboundMDB.onMessage: com.bea.wli.sb.transports.TransportException: <jca-transport-application-error xmlns="http://www.bea.com/wli/sb/transports/jca">
<jca-transport-error-message>Invoke JCA outbound service failed with application error</jca-transport-error-message>
<jca-runtime-fault-detail>
<eis-error-code>501</eis-error-code>
<eis-error-message>501 Syntax error</eis-error-message>
<exception>com.bea.wli.sb.transports.jca.JCATransportException: oracle.tip.adapter.sa.api.JCABindingException: oracle.tip.adapter.sa.impl.fw.ext.org.collaxa.thirdparty.apache.wsif.WSIFException: servicebus:/WSDL/Phoenix_PurchaseOrder/WriteToWMOS_FTP [ Put_ptt::Put(opaque) ] - WSIF JCA Execute of operation 'Put' failed due to: Error in logging in.
Error in logging in.
Unable to log in to the server.
; nested exception is:
BINDING.JCA-11439
Error in logging in.
Error in logging in.
Unable to log in to the server.
Please ensure userid and password specified to login to the server is correct.




To understand what is going on, I enable debug flag alsb-jca-framework-adapter-debug as explained here



All I get is :




Caused by: BINDING.JCA-11439
Error in logging in.
Error in logging in.
Unable to log in to the server.
Please ensure userid and password specified to login to the server is correct.

at oracle.tip.adapter.ftp.FTPClient.regularLogin(FTPClient.java:1630)
at oracle.tip.adapter.ftp.FTPClient.login(FTPClient.java:1593)
at oracle.tip.adapter.ftp.FTPAgent.login(FTPAgent.java:1170)
at oracle.tip.adapter.ftp.FTPAgent.preCall(FTPAgent.java:1632)
at oracle.tip.adapter.ftp.FTPAgent.validateOutputDir(FTPAgent.java:1230)
at oracle.tip.adapter.file.outbound.FileInteraction.validateDirectory(FileInteraction.java:2676)
at oracle.tip.adapter.file.outbound.FileInteraction.executeFileWrite(FileInteraction.java:547)
at oracle.tip.adapter.ftp.outbound.FTPInteraction.execute(FTPInteraction.java:251)
at oracle.tip.adapter.sa.impl.fw.wsif.jca.WSIFOperation_JCA.performOperation(WSIFOperation_JCA.java:529)
... 62 more





and there is no way to log the actual username/password it is using to login into the FTP server


I am using Filezilla Server, I disable the Miscellaneous/Don't show password in logs, and I enable logging on the server.

What I find is disconcerting:


(000033) 13-11-2011 21:46:48 - (not logged in) (127.0.0.1)> USER
(000033) 13-11-2011 21:46:48 - (not logged in) (127.0.0.1)> 501 Syntax error


while the normal sequence should be:


(000037) 13-11-2011 21:57:07 - (not logged in) (fe80::5950:1b46:fefe:aa61)> USER someuser
(000037) 13-11-2011 21:57:07 - (not logged in) (fe80::5950:1b46:fefe:aa61)> 331 Password required for someuser
(000037) 13-11-2011 21:57:07 - (not logged in) (fe80::5950:1b46:fefe:aa61)> PASS somepassword
(000037) 13-11-2011 21:57:07 - someuser (fe80::5950:1b46:fefe:aa61)> 230 Logged on


normally after USER I should see a username.... this means that the mapping fails.

The case is reported here


I notice that the log statement reports "anonymous". If you go to deployment, FtpAdapter, Security, Principal you can set "weblogic" and principal, and make sure that you also use weblogic in the Credential Mapping.
This is not enough.

In the $inbound of the OSB request I notice:


<con:security>
<con:transportClient>
<con:username><anonymous></con:username>
</con:transportClient>
</con:security>



so I create a weblogicServiceAccount for username weblogic, associate it to the Proxy JMS Service Account (hoping to make the OSB proxy "run as" the weblogic username, but I get this in the logs:


ServiceAccountRuntimeManagerImpl.getUsernamePasswordCredential = this: com.bea.wli.sb.svcacct.ServiceAccountRuntimeManagerImpl@17d3da

Could not find credentials on admin server: java.lang.IllegalArgumentException: com.bea.wli.sb.management.configuration.ServiceAccountRuntime is not an interface

com.bea.wli.sb.svcacct.ServiceAccountRuntimeCache@1e49c6b$ServiceAccountRuntimeCache.get(Acme_PurchaseOrder/weblogicServiceAccount)

ServiceAccountRuntimeCache.get(Acme_PurchaseOrder/weblogicServiceAccount) returned ServiceAccountRuntime[Acme_PurchaseOrder/weblogicServiceAccount]



and the $inbound still shows anonymous user


Anyway, at the end I do:

Deployments/FtpAdapter/Security/Credential Mapping/New/Unauthenticated User and I map it to the FTP user.... works like magic!


The alternative is to specify a username/password in the JCA Outbound Connection Pool instance properties (there are 55 properties, only 10 shown in the first page... they are in alphabetical order, so yuoi must go to the last page)





One day I will figure out how to attach a WebLogic principal to an incoming JMS request... security has always been my Achilles' heel

Sunday, November 13, 2011

WebLogic on YouTube

http://www.youtube.com/OracleWebLogic


I am watching these videos, some of them are quite cool...

Thursday, November 10, 2011

JCATransport:381987 in JCA FTP Adapter

I have created a FTP Adapter in JDeveloper 11.1.1.5 and imported in OSB.

When I activate, I get this beautiful conflict


[JCATransport:381987]An error occured while validating JCA transport endpoint. JNDI lookup with URL: jca://eis/ftp/FtpAdapter failed. Missing JNDI configuration such as undeployed or misconfigured JCA Adapter RAR or connection factory.



Well, embarrassingly enough it turns out that the actual JNDI Binding name is eis/Ftp/FtpAdapter and not eis/ftp/FtpAdapter (upper case F) as proposed by

I wonder how such a blunder could take place in JDeveloper...



Wednesday, November 9, 2011

OSB Validate action failed validation

The Exception logged is quite useless. You must examine the $fault in an error handler, to determine what went wrong:

<con:fault xmlns:con="http://www.bea.com/wli/sb/context">
  <con:errorCode>BEA-382505</con:errorCode>
  <con:reason>OSB Validate action failed validation</con:reason>
  <con:details>
    <con1:ValidationFailureDetail xmlns:con1="http://www.bea.com/wli/sb/stages/transform/config">
      <con1:message>string length (4) is greater than maxLength facet (3) for UOMType in namespace http://acme.pippo.com/po</con1:message>
      <con1:xmlLocation>
        <po:UOM xmlns:po="http://acme.pippo.com/po">PAL</po:UOM>
      </con1:xmlLocation>
      <con1:message>string length (4) is greater than maxLength facet (3) for UOMType in namespace http://acme.pippo.com/po</con1:message>
      <con1:xmlLocation>
        <po:UOM xmlns:po="http://acme.pippo.com/po">PAL</po:UOM>
      </con1:xmlLocation>
    </con1:ValidationFailureDetail>
  </con:details>
  <con:location>
    <con:node>PPL_acme_PO_FFMW_FilePoller_file</con:node>
    <con:pipeline>PPL_acme_PO_FFMW_FilePoller_file_request</con:pipeline>
    <con:stage>Validation</con:stage>
    <con:path>request-pipeline</con:path>
  </con:location>
</con:fault>



For some funny reason, the error message and location are repeated twice.

Installing OSB 10.3.5 on a Windows machine where you are not the Administrator

The installer needs to create a directory
C:\Program Files\Oracle\Inventory

and you won't be able unless you run as Administrator.

Run your installer right-clicking C:\tmp\Disk1\install\win32\setup.exe and choose "Run as administrator". That should do the job.

Anatomy of a JCA File Adapter parsing failure

If you submit a "broken" file to a File Adapter associated to a nXSD transformation, you might expect something like this to happen (see after).

To be noticed:

* eventually, the file is moved to the error directory

* The entry point to the translation is oracle.tip.pc.services.translation.xlators.nxsd.NXSDTranslatorImpl.translateFromNative


* The exception is a ORABPEL-11168
* The Proxy Service is not invoked, so there is no way to trace this error in OSB.

* To trace the error, you must implement a RejectedMessageHandler
* In alternative, you could "grep" the logs for ORABPEL-11168 with WLDF, but this solution really sucks

So implementing a RejectedMessageHandler seems to me the best way to trace the error. This requires more investigation.


<08-Nov-2011 22:39:57 o'clock CET> <Info> <JCA_FRAMEWORK_AND_ADAPTER> <pierrepc> <osb_server1> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <9218d6466d04a9d6:5003231f:133830ed055:-8000-0000000000000031> <1320788397613> <BEA-000000> <Error while translating inbound file : po00000BROKEN.dat
ORABPEL-11168

Error while reading native data.
[Line=1, Col=1] Expected "," for the data starting at the specified position, while trying to read the data for "element with name OrderNumber", using "style" as "terminated" and "terminatedBy" as ",", but not found.
Ensure that ",", exists for the data starting at the specified position.

at oracle.tip.pc.services.translation.xlators.nxsd.NXSDStyleBasedReader.readTerminatedStyle(NXSDStyleBasedReader.java:338)
at oracle.tip.pc.services.translation.xlators.nxsd.NXSDTranslatorImpl.readTerminatedStyle(NXSDTranslatorImpl.java:2771)
at oracle.tip.pc.services.translation.xlators.nxsd.NXSDTranslatorImpl.readNativeData(NXSDTranslatorImpl.java:2841)
at oracle.tip.pc.services.translation.xlators.nxsd.NXSDTranslatorImpl.processScalarType(NXSDTranslatorImpl.java:3600)
at oracle.tip.pc.services.translation.xlators.nxsd.NXSDTranslatorImpl.processElement(NXSDTranslatorImpl.java:3800)
at oracle.tip.pc.services.translation.xlators.nxsd.NXSDTranslatorImpl.parseNXSD(NXSDTranslatorImpl.java:1327)
at oracle.tip.pc.services.translation.xlators.nxsd.NXSDTranslatorImpl.processGroup(NXSDTranslatorImpl.java:3705)
at oracle.tip.pc.services.translation.xlators.nxsd.NXSDTranslatorImpl.parseNXSD(NXSDTranslatorImpl.java:1334)
at oracle.tip.pc.services.translation.xlators.nxsd.NXSDTranslatorImpl.processComplexType(NXSDTranslatorImpl.java:3841)
at oracle.tip.pc.services.translation.xlators.nxsd.NXSDTranslatorImpl.parseNXSD(NXSDTranslatorImpl.java:1330)
at oracle.tip.pc.services.translation.xlators.nxsd.NXSDTranslatorImpl.processElement(NXSDTranslatorImpl.java:3806)
at oracle.tip.pc.services.translation.xlators.nxsd.NXSDTranslatorImpl.parseNXSD(NXSDTranslatorImpl.java:1327)
at oracle.tip.pc.services.translation.xlators.nxsd.NXSDTranslatorImpl.processGroup(NXSDTranslatorImpl.java:3705)
at oracle.tip.pc.services.translation.xlators.nxsd.NXSDTranslatorImpl.parseNXSD(NXSDTranslatorImpl.java:1334)
at oracle.tip.pc.services.translation.xlators.nxsd.NXSDTranslatorImpl.processComplexType(NXSDTranslatorImpl.java:3841)
at oracle.tip.pc.services.translation.xlators.nxsd.NXSDTranslatorImpl.parseNXSD(NXSDTranslatorImpl.java:1330)
at oracle.tip.pc.services.translation.xlators.nxsd.NXSDTranslatorImpl.processElement(NXSDTranslatorImpl.java:3806)
at oracle.tip.pc.services.translation.xlators.nxsd.NXSDTranslatorImpl.parseNXSD(NXSDTranslatorImpl.java:1327)
at oracle.tip.pc.services.translation.xlators.nxsd.NXSDTranslatorImpl.doTranslateFromNative(NXSDTranslatorImpl.java:846)
at oracle.tip.pc.services.translation.xlators.nxsd.NXSDTranslatorImpl.translateFromNative(NXSDTranslatorImpl.java:602)
at oracle.tip.adapter.file.inbound.InboundTranslatorDelegate.xlate(InboundTranslatorDelegate.java:314)
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)
>
####<08-Nov-2011 22:39:57 o'clock CET> <Info> <JCA_FRAMEWORK_AND_ADAPTER> <pierrepc> <osb_server1> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <9218d6466d04a9d6:5003231f:133830ed055:-8000-0000000000000031> <1320788397614> <BEA-000000> <Since a translation exception was thrown, this indicates that it is a non-debatching scenario.>
####<08-Nov-2011 22:39:57 o'clock CET> <Info> <JCA_FRAMEWORK_AND_ADAPTER> <pierrepc> <osb_server1> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <9218d6466d04a9d6:5003231f:133830ed055:-8000-0000000000000031> <1320788397615> <BEA-000000> <Failed to translate file : {C:\acme\ffmw\po\in\po00000BROKEN.dat}>
####<08-Nov-2011 22:39:57 o'clock CET> <Info> <JCA_FRAMEWORK_AND_ADAPTER> <pierrepc> <osb_server1> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <9218d6466d04a9d6:5003231f:133830ed055:-8000-0000000000000031> <1320788397615> <BEA-000000> <Sending message to Adapter Framework for rejection to user-configured rejection handlers : {
file=C:\acme\ffmw\po\in\po00000BROKEN.dat, Exception=ORABPEL-11168

Error while reading native data.
[Line=1, Col=1] Expected "," for the data starting at the specified position, while trying to read the data for "element with name OrderNumber", using "style" as "terminated" and "terminatedBy" as ",", but not found.
Ensure that ",", exists for the data starting at the specified position.

}>
####<08-Nov-2011 22:39:57 o'clock CET> <Warning> <JCA_FRAMEWORK_AND_ADAPTER> <pierrepc> <osb_server1> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <9218d6466d04a9d6:5003231f:133830ed055:-8000-0000000000000031> <1320788397616> <BEA-000000> <onReject: The resource adapter 'File Adapter' requested handling of a malformed inbound message. However, the following activation property has not been defined: 'rejectedMessageHandlers'. Please define it and redeploy. Will use the default Rejection Directory file://jca\Read\rejectedMessages for now.>
####<08-Nov-2011 22:39:57 o'clock CET> <Warning> <JCA_FRAMEWORK_AND_ADAPTER> <pierrepc> <osb_server1> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <9218d6466d04a9d6:5003231f:133830ed055:-8000-0000000000000031> <1320788397616> <BEA-000000> <onReject: Sending invalid inbound message to Rejection Handler: >
####<08-Nov-2011 22:39:57 o'clock CET> <Info> <JCA_FRAMEWORK_AND_ADAPTER> <pierrepc> <osb_server1> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <9218d6466d04a9d6:5003231f:133830ed055:-8000-0000000000000031> <1320788397618> <BEA-000000> <Handing rejected message to DEFAULT rejection handler: file://jca\Read\rejectedMessages since none of the configured rejection handlers [] succeeded.>
####<08-Nov-2011 22:39:57 o'clock CET> <Info> <JCA_FRAMEWORK_AND_ADAPTER> <pierrepc> <osb_server1> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <9218d6466d04a9d6:5003231f:133830ed055:-8000-0000000000000031> <1320788397622> <BEA-000000> <Copying file :C:\acme\ffmw\po\in\po00000BROKEN.dat to user-defined archive directory for files with errors :C:\acme\ffmw\po\error>



See also this Oracle documentation on the rejectedMessageHandler topic

Errors or faults arising after the message is posted to Service Infrastructure layer are not rejected. These faulted messages are handled by the Service Infrastructure components and will not be considered as rejected messages.

Adapters and other binding components (for example, WS Binding Component) reject messages which error out at the binding level, that is, before entering the Service Infrastructure layer. All rejected messages are stored in the Database with payload.


Tuesday, November 8, 2011

JCA File Adapter and Error files

Oracle implementation of the File Adapter is the class:
oracle.tip.adapter.file.inbound.FileActivationSpec

you customize the adapter in the .JCA file

One of its parameters is

PhysicalErrorArchiveDirectory

and it is documented here

For instance if you submit an empty file, the File Adapter will fail and move the file to the Error directory. In the logs I find:


<Warning> <JCA_FRAMEWORK_AND_ADAPTER> <BEA-000000> <onReject: The resource adapter 'File Adapter' requested handling of a malformed inbound message. However, the following activation property has not been defined: 'rejectedMessageHandlers'. Please define it and redeploy. Will use the default Rejection Directory file://jca\Read\rejectedMessages for now.>

<Warning> <JCA_FRAMEWORK_AND_ADAPTER> <BEA-000000> <onReject: Sending invalid inbound message to Rejection Handler: >


In case of error in the Proxy Service consuming the message, at proxy level you should set jca.retry.count and jca.retry.interval

<jca:endpoint-properties>
<jca:endpoint-property>
<jca:name>jca.retry.count</jca:name>
<jca:value>3</jca:value>
</jca:endpoint-property>
<jca:endpoint-property>
<jca:name>jca.retry.interval</jca:name>
<jca:value>40</jca:value>
</jca:endpoint-property>
</jca:endpoint-properties>

with these settings, you will see these messages:

Failed to send message {C:\acme\ffmw\po\in\po000000002.dat} to Adapter Framework due to Retriable Exception, the worker will sleep for the configured retryInterval[40000] msecs

Retry Interval will be bounded to [30000] msecs since we're using a global processor thread pool and the current retryInterval is[40000] msecs

Since Retry Interval is specified, the processor will disable for[30000] msecs to throttle


40 seconds after, you get:

The adapter will not process [C:\acme\ffmw\po\in\po000000002.dat] since it has been processed earlier

onReject: Sending invalid inbound message to Rejection Handler:

Handing rejected message to DEFAULT rejection handler: file://jca\Read\rejectedMessages since none of the configured rejection handlers [] succeeded.

Copying file :C:\acme\ffmw\po\in\po000000002.dat to user-defined archive directory for files with errors :C:\acme\ffmw\po\error

The adapter has handled the poisoned file [C:\acme\ffmw\po\in\po000000002.dat]




So, only if you set the retry count the file will eventually be moved to the error directory also on "application" error triggered by the Proxy Service.

Monday, November 7, 2011

Eclipse: Interpreter: Weblogic 10.3.5 WLST Interpreter not found

Apparently in Eclipse, if you Import an existing project with the "Oracle WebLogic Scripting Tools (WLST) Support" facet, this is not enough to have the facet fully configured in your new project.
You will get an error "Interpreter: Weblogic 10.3.5 WLST Interpreter not found".
Workaround: create the Utiliy project, enable the "Oracle WebLogic Scripting Tools (WLST) Support" facet and copy the code manually.

I will not miss too much Eclipse... or maybe yes, it could be worse, it could rain...

Sunday, November 6, 2011

Hudson project "depends" on another project

I have Project A, and I want to execute Project B BEFORE I run A.

In Ant, I would simply say
target A depends="B"

In Hudson, they made it more workaroundish.

In Project B, enable "Trigger builds remotely (e.g., from scripts)", specify a token (eg TOKEN); to trigger the job you do:
wget http://localhost:8080/job/OSBProject1/build?token=TOKEN

In Widows (the Windows users commit often suicide) you can use Wget for Widows: http://gnuwin32.sourceforge.net/packages/wget.htm

see also here

An alternative is using the Parametrized Trigger Plugin and have a dummy Project C run B and A

All this is very silly, there should be a pre-dependencies and post-dependencies list.

Getting file info from JCA File Poller

logging $inbound/ctx:transport/ctx:request/tp:headers gives this:

<tran:headers xsi:type="jca:JCARequestHeadersXML" xmlns:jca="http://www.bea.com/wli/sb/transports/jca" xmlns:tran="http://www.bea.com/wli/sb/transports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <tran:user-header name="jca.file.CreationTime" value="0"/>
  <jca:SOAPAction>Read</jca:SOAPAction>
  <jca:jca.file.FileName>po000000001.dat</jca:jca.file.FileName>
  <jca:jca.file.Directory>C:\acme\po\in</jca:jca.file.Directory>
  <jca:jca.file.Size>113</jca:jca.file.Size>
  <jca:jca.file.Batch>z_qjc5GlR6b6iHDgdbExXlDoQiEkb7g2BnTbpmrhd7E.</jca:jca.file.Batch>
  <jca:jca.file.BatchIndex>1</jca:jca.file.BatchIndex>
  <jca:jca.file.LastModifiedTime>1320482562574</jca:jca.file.LastModifiedTime>
</tran:headers>



Filename can be retrieved this way:

$inbound/ctx:transport/ctx:request/tp:headers/tp:headers/jca:jca.file.FileName/text()

where
ctx="http://www.bea.com/wli/sb/context"
tp="http://www.bea.com/wli/sb/transports"
jca="http://www.bea.com/wli/sb/transports/jca"

Microsoft Office Driven Design (MODD)

I just thought of branding this new acronym MODD, do indicate projects where Visio, Word and Excel documents are reputed of much more importance than good functional testable performing working code, and proper Configuration Management.

The acronym is already used for "Microsoft Office Document Designer", I hope Microsoft Lawyers won't prosecute me....

Saturday, November 5, 2011

JCA File Adapter, File read vs Synchronous File Read, Sorting Files with ListSorter

In a nutshell, the Synchronous option doesn't create a File Poller Thread, but stops execution of an existing Thread (Message Flow) to read a file with a specified name.
In the parametrization of the File Adapter, the only difference is the existence of the "File Name" attribute. This is explained in detail here.

In the official documentation, this picture is wrong:

http://download.oracle.com/docs/cd/E15523_01/integration.1111/e10231/adptr_file.htm#BABEJGJB


it should be rather this:



Bear in mind that not all properties are shown in the JDeveloper wizard. You will have to hack the JCA file for some of them.
Their list is here.

A very interesting option is ListSorter :

ListSorter="oracle.tip.adapter.file.sorter.TimestampSorterAscending" allows you to process files in order of timestamp.

You can provide your own ListSorter: just implement a java.util.Comparator, you will receive 2 objects oracle.tip.adapter.file.FileInfo, so the available properties on which you can sort are:

fileName
compressedFileName
fileExtension
fullPath
compressedFullPath
timestamp
size
processed
isActive
fileList
batchId
processHeaderOnly
headerOnlyNoDelete
distributed
inputDirectory
compressedInputDirectory
rootDirectory
compressedRootDirectory
readOnly
creationTime
raw
primaryKey
originalPrimaryKey
clusteredFileList
fileType
singleThreaded
status
usePreciseTimestamp
poller
properties

However, bear in mind that the documentation says that you should have a SINGLE THREAD to make the sorting work


When files must be processed by Oracle File and FTP Adapters in a particular order, you must configure the sorting parameters. For example, you can configure the sorting parameters for Oracle File and FTP Adapters to process files in ascending or descending order by time stamps.
You must meet the following prerequisites for sorting scenarios of Oracle File and FTP Adapters:
• Use a synchronous operation
• Add the following property to the inbound JCA file:

property name="ListSorter" value="oracle.tip.adapter.file.inbound.listing.TimestampSorterAscending"
property name="SingleThreadModel" value="true"



Friday, November 4, 2011

OSB, customizing the customization file ALSBCustomizationFile.xml

I hate having to modify the ALSBCustomizationFile.xml with tokens to be replaced or, even worse, maintain a separate ALSBCustomizationFile.xml per environment.

And I believe the "find and replace" strategy is weak and error-prone.

Better define in a separate file what you want to customize and its new value. One file per environment. Sweet and simple.

At last I can put all pieces together:


Your "mycustomizations.properties" file should be like this:

#ownerType.ownerPath.envValueType=newvalue
ProxyService:OSBProject1/ProxyService1:Service URI=/OSBProject1/ProxyServicePluto

and this is the Groovy code:


import groovy.xml.XmlUtil

/*
 * Lookup customization file
 * Search //cus:envValueAssignments[(cus:envValueAssignments/xt:owner/xt:type/text() == $1 
 *          AND //cus:envValueAssignments/xt:owner/xt:path/text() = $2)][xt:envValueType == $3]
 * and replace their xt:value with $4
 *  
 */

def customizations = new XmlSlurper().parse("ALSBCustomizationFile.xml").declareNamespace(xt: 'http://www.bea.com/wli/config/xmltypes',xsi: 'http://www.w3.org/2001/XMLSchema-instance', cus : 'http://www.bea.com/wli/config/customizations')

//println XmlUtil.serialize( customizations )

File theInfoFile = new File("mycustomizations.properties")

theInfoFile.eachLine { line ->
  if ( (line.trim().size() == 0) || (line.trim().startsWith("#")) ) {
   // ignore
  } else {
    words = line.split("=")
    keys = words[0].split(":")
    value = words[1]

  ownerType = keys[0]
  ownerPath = keys[1]
  envValueType = keys[2]
  
  customizations.'cus:customization'.each {

   if (it.'@xsi:type' == "cus:EnvValueCustomizationType") {
    println "FOUND"
    for (item in it.'cus:envValueAssignments') {
     if ( (item.'xt:envValueType' == envValueType) &&  (item.'xt:owner'.'xt:type' = ownerType) &&  (item.'xt:owner'.'xt:path' = ownerPath) ) {
      println "ITEM " + envValueType + " " + ownerType + " " + ownerPath + ", before is " + item.'xt:value'
      item.'xt:value'.replaceBody(value)
      println "ITEM " + envValueType + " " + ownerType + " " + ownerPath + ",  after is " + item.'xt:value'
     }
    }
   } // if
  } // each
   } // if else
}
 

println XmlUtil.serialize( customizations )



Groovy is great but not intuitive and self-explanatory to use.... Groovy plugin for Eclipse does code completion but can't introspect the runtime type of a variable, of course...

Groovy, updating XML with XmlSlurper

Sometimes you don't want only to parse XML, but also modify XML with XmlSlurper.


XmlSlurper.parse(...) returns an object of type GPathResult

To change the content of a node, use replaceBody()


For instance, with the XML file of the previous post, you can change a value of an element this way:


import groovy.xml.XmlUtil

/*
 * Lookup customization file
 * Search //cus:envValueAssignments[(cus:envValueAssignments/xt:owner/xt:type/text() == $1 
 *          AND //cus:envValueAssignments/xt:owner/xt:path/text() = $2)][xt:envValueType == $3]
 * and replace their xt:value with $4
 *  
 */

def customizations = new XmlSlurper().parse("ALSBCustomizationFile.xml").declareNamespace(xt: 'http://www.bea.com/wli/config/xmltypes',xsi: 'http://www.w3.org/2001/XMLSchema-instance', cus : 'http://www.bea.com/wli/config/customizations')

//println XmlUtil.serialize( customizations )

customizations.'cus:customization'.each {
    println "UNO"
 if (it.'@xsi:type' == "cus:EnvValueCustomizationType") {
  println "TROVATO"
  for (item in it.'cus:envValueAssignments') {
   if (item.'xt:envValueType' == 'Service URI') {
    println "ITEM Service URI, before is " + item.'xt:value'
    item.'xt:value'.replaceBody("ciao")
    println "ITEM Service URI, after  is " + item.'xt:value'
   }
  }
 }
}


println XmlUtil.serialize( customizations )



The document is actually updated the second time you print it.

It was tough to figure this out, the official article on "updating XML with XmlSlurper" suggests to simply assign:

item.'xt:value' = "ciao"

but it simply doesn't work

Wednesday, November 2, 2011

Groovy: parsing XML with namespaces

99% of the examples on the Internet show how to parse XML without namespaces.

Unfortunately in real life 99% of the XML HAS namespaces :o(

Here is an example, the source XML is:

<?xml version="1.0" encoding="UTF-8"?>
<cus:Customizations xmlns:cus="http://www.bea.com/wli/config/customizations" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xt="http://www.bea.com/wli/config/xmltypes">
  <cus:customization xsi:type="cus:EnvValueCustomizationType">
    <cus:description/>
    <cus:envValueAssignments>
      <xt:envValueType>UDDI Auto Publish</xt:envValueType>
      <xt:location xsi:nil="true"/>
      <xt:owner>
        <xt:type>ProxyService</xt:type>
        <xt:path>OSBProject1/ProxyService1</xt:path>
      </xt:owner>
      <xt:value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema">false</xt:value>
    </cus:envValueAssignments>
    <cus:envValueAssignments>
      <xt:envValueType>Service URI</xt:envValueType>
      <xt:location xsi:nil="true"/>
      <xt:owner>
        <xt:type>ProxyService</xt:type>
        <xt:path>OSBProject1/ProxyService1</xt:path>
      </xt:owner>
      <xt:value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema">/OSBProject1/ProxyServicePippo</xt:value>
    </cus:envValueAssignments>
  </cus:customization>
  <cus:customization xsi:type="cus:FindAndReplaceCustomizationType">
    <cus:description/>
    <cus:query>
      <xt:resourceTypes>ProxyService</xt:resourceTypes>
      <xt:envValueTypes>UDDI Auto Publish</xt:envValueTypes>
      <xt:envValueTypes>Service URI</xt:envValueTypes>
      <xt:refsToSearch xsi:type="xt:ResourceRefType">
        <xt:type>ProxyService</xt:type>
        <xt:path>OSBProject1/ProxyService1</xt:path>
      </xt:refsToSearch>
      <xt:includeOnlyModifiedResources>false</xt:includeOnlyModifiedResources>
      <xt:searchString>Search String</xt:searchString>
      <xt:isCompleteMatch>false</xt:isCompleteMatch>
    </cus:query>
    <cus:replacement>Replacement String</cus:replacement>
  </cus:customization>
  <cus:customization xsi:type="cus:ReferenceCustomizationType">
    <cus:description/>
  </cus:customization>
</cus:Customizations>


The Groovy-XmlParser is:

def customizations = new XmlParser().parse("ALSBCustomizationFile.xml")
def cus = new groovy.xml.Namespace("http://www.bea.com/wli/config/customizations")
def xt = new groovy.xml.Namespace("http://www.bea.com/wli/config/xmltypes")
def xsi = new groovy.xml.Namespace("http://www.w3.org/2001/XMLSchema-instance")

customizations[cus.customization].each {
    if (it.attributes()[xsi.type] == 'cus:EnvValueCustomizationType') {
        println "FOUND!"
    }

    def values = it[cus.envValueAssignments][xt.envValueType]
    for (value in values) {
        print value
    }
}


Result:

FOUND!
{http://www.bea.com/wli/config/xmltypes}envValueType[attributes={}; value=[UDDI Auto Publish]]{http://www.bea.com/wli/config/xmlty
pes}envValueType[attributes={}; value=[Service URI]]


The Groovy-XmlSlurper way is:

def customizations = new XmlSlurper().parse("ALSBCustomizationFile.xml").declareNamespace(xt: 'http://www.bea.com/wli/config/xmltypes',xsi: 'http://www.w3.org/2001/XMLSchema-instance', cus : 'http://www.bea.com/wli/config/customizations')

println customizations

customizations.'cus:customization'.each {
    println "UNO"
 if (it.'@xsi:type' == "cus:EnvValueCustomizationType") {
  println "TROVATO"
 }
 
}


The very annoying difference between XmlParser and XmlSlurper is that in the first you use ns.part and in the other ns:part

java.lang.NoSuchMethodError: antlr/LexerSharedInputState.getTokenStartColumn()

If you get this error

java.lang.NoSuchMethodError: antlr/LexerSharedInputState.getTokenStartColumn()

when running Groovy from the CLI, be aware that you might have in the CLASSPATH some old antlr jars.

For instance, my CLASSPATH was:

echo %CLASSPATH%

C:\bea1035\patch_wls1035\profiles\default\sys_manifest_classpath\weblogic_patch.jar;C:\bea1035\patch_oepe1050\profiles\default\sys_manifest_classpath\weblogic_patch.jar;C:\bea1035\patch_ocp360\profiles\default\sys_manifest_classpath\weblogic_patch.jar;C:\bea1035\patch_jdev1111\profiles\default\sys_manifest_classpath\weblogic_patch.jar;C:\bea1035\JROCKI~1.2-4\lib\tools.jar;C:\bea1035\WLSERV~1.3\server\lib\weblogic_sp.jar;C:\bea1035\WLSERV~1.3\server\lib\weblogic.jar;C:\bea1035\modules\features\weblogic.server.modules_10.3.5.0.jar;C:\bea1035\WLSERV~1.3\server\lib\webservices.jar;C:\bea1035\modules\ORGAPA~1.1/lib/ant-all.jar;C:\bea1035\modules\NETSFA~1.0_1/lib/ant-contrib.jar;

If you do

set CLASSPATH=""

this should fix the problem, since groovy.bat will pick up the right CLASSPATH it needs to run.

XML parsing in Python/Jython/ WLST: lxml , libxml2 and minidom

you have the option of using libxml2 http://users.skynet.be/sbi/libxml-python/

but I read better things about http://lxml.de/. To use lxml you must first install http://users.skynet.be/sbi/libxml-python/.


To determine which version of Python you are running in WLST, do

import sys
sys.version_info


for instance with WLS 10.3.5 I get:

(2, 2, 1, 'final', 0)

So the most recent version of libxml2 available for Python 2.2.1 is the 2.6.9:

http://users.skynet.be/sbi/libxml-python/libxml2-python-2.6.9.win32-py2.2.exe

Anyway lxml requires Python 2.4 as a minimum, so you are screwed. In any case WLST uses Jython, not Python, so again you are screwed unless you install Python.


Alternatively, use minidom which is supported in WLST:

from xml.dom.minidom import parse
dom1 = parse('ALSBCustomizationFile.xml'
)

dom1 is a xml.dom.minidom.Document

here the javadoc

then you can do:

envValueAssignments=dom1.getElementsByTagName('cus:envValueAssignments')

and you get a NodeList http://docs.python.org/library/xml.dom.html

if you do:


print envValueAssignments[0].__class__

it says
xml.dom.minidom.Element
whose javadoc is here


you can also do

print envValueAssignments[0].toxml()


Honestly parsing is very painful using a DOM-based approach.
I would rather use Groovy which has got a much more intuitive semantic approach to xml parsing.

Tuesday, November 1, 2011

Updated version of import.py and exportFromWorkspace for OSB 10.3.5

Things have slightly changed and since the previous versions you must adjust the classpaths.

Copy the scripts into a directory and run:

c:\apps\ant\bin\ant -verbose exportFromWorkspace
c:\apps\ant\bin\ant -verbose import

Remember that your workspace should contain also a OSBConfiguration


http://javatoolsforweblogic.googlecode.com/svn/trunk/OSBImport/build.properties
http://javatoolsforweblogic.googlecode.com/svn/trunk/OSBImport/build.xml
http://javatoolsforweblogic.googlecode.com/svn/trunk/OSBImport/import.properties
http://javatoolsforweblogic.googlecode.com/svn/trunk/OSBImport/import.py


The scripts are really raw and need refactoring, but they worked on my machine

New book on Oracle Service Bus



Oracle Service Bus 11g development cookbook.

Authors are the Gotha of Oracle SOA:

Guido Schmutz, Edwin Biemond , Jan van Zoggel , Mischa Kölliker , Eric Elzinga

I am very proud of being friend to Jan van Zoggel, probably one of the friendliest Oracle consultants.

I have already pre-bought the book, and looking forward to reading it!

taskdef class weblogic.ant.taskdefs.management.WLSTTask cannot be found

In my build.xml I have declared

taskdef name="wlst" classname="weblogic.ant.taskdefs.management.WLSTTask"

and I get the blessed error



The solution could simply be adding a "classpath" element to the taskdef:

taskdef classpath="${bea.home}/wlserver_10.3/server/lib/weblogic.jar" name="wlst" classname="weblogic.ant.taskdefs.management.WLSTTask"


In fact taskdef uses the same attributes as typedef

http://ant.apache.org/manual/Tasks/typedef.html