Friday, December 09, 2016

Flow Control not possible if no key is declared in your target datastore. -ODI


I created a simple ODI Mapping in SOA 12c and tried to test the mapping and i got this error message

Flow Control not possible if no key is declared in your target datastore.

Please check the Validation Results window for more information



Wednesday, March 23, 2016

Build a First Hello World Sample in Anytime Studio

I started my lab with the Mulesoft document

https://docs.mulesoft.com/mule-fundamentals/v/3.7/build-a-hello-world-application

I created my sample application and tried to deploy it in the default integrated server of mulesoft

I deployed this to the default server of Mulesoft and i got below error

Failed to deploy artifact 'helloworld', see below +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
org.mule.module.launcher.DeploymentStartException: BindException: Address already in use: bind
at org.mule.module.launcher.application.DefaultMuleApplication.start(DefaultMuleApplication.java:156) ~[mule-module-launcher-3.7.3.jar:3.7.3]
at org.mule.module.launcher.artifact.ArtifactWrapper$4.execute(ArtifactWrapper.java:98) ~[mule-module-launcher-3.7.3.jar:3.7.3]
at org.mule.module.launcher.artifact.ArtifactWrapper.executeWithinArtifactClassLoader(ArtifactWrapper.java:129) ~[mule-module-launcher-3.7.3.jar:3.7.3]
at org.mule.module.launcher.artifact.ArtifactWrapper.start(ArtifactWrapper.java:93) ~[mule-module-launcher-3.7.3.jar:3.7.3]
at org.mule.module.launcher.DefaultArtifactDeployer.deploy(DefaultArtifactDeployer.java:26) ~[mule-module-launcher-3.7.3.jar:3.7.3]
at org.mule.module.launcher.DefaultArchiveDeployer.guardedDeploy(DefaultArchiveDeployer.java:324) ~[mule-module-launcher-3.7.3.jar:3.7.3]
at org.mule.module.launcher.DefaultArchiveDeployer.deployArtifact(DefaultArchiveDeployer.java:345) ~[mule-module-launcher-3.7.3.jar:3.7.3]
at org.mule.module.launcher.DefaultArchiveDeployer.deployPackagedArtifact(DefaultArchiveDeployer.java:163) ~[mule-module-launcher-3.7.3.jar:3.7.3]
at org.mule.module.launcher.DefaultArchiveDeployer.deployPackagedArtifact(DefaultArchiveDeployer.java:268) ~[mule-module-launcher-3.7.3.jar:3.7.3]
at org.mule.module.launcher.DefaultArchiveDeployer.deployPackagedArtifact(DefaultArchiveDeployer.java:83) ~[mule-module-launcher-3.7.3.jar:3.7.3]
at org.mule.module.launcher.DeploymentDirectoryWatcher.deployPackedApps(DeploymentDirectoryWatcher.java:275) ~[mule-module-launcher-3.7.3.jar:3.7.3]
at org.mule.module.launcher.DeploymentDirectoryWatcher.start(DeploymentDirectoryWatcher.java:150) ~[mule-module-launcher-3.7.3.jar:3.7.3]
at org.mule.module.launcher.MuleDeploymentService.start(MuleDeploymentService.java:104) ~[mule-module-launcher-3.7.3.jar:3.7.3]
at org.mule.module.launcher.MuleContainer.start(MuleContainer.java:170) ~[mule-module-launcher-3.7.3.jar:3.7.3]
at org.mule.tooling.server.application.ApplicationDeployer.main(ApplicationDeployer.java:15) ~[tooling-support-3.7.3.jar:?]
Caused by: org.mule.api.lifecycle.LifecycleException: Failed to invoke lifecycle phase "start" on object: org.mule.module.http.internal.listener.DefaultHttpListenerConfig@2ed1d9ea
at org.mule.lifecycle.phases.DefaultLifecyclePhase.applyLifecycle(DefaultLifecyclePhase.java:248) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.RegistryLifecycleCallback.doApplyLifecycle(RegistryLifecycleCallback.java:91) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.RegistryLifecycleCallback.onTransition(RegistryLifecycleCallback.java:67) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.RegistryLifecycleManager.invokePhase(RegistryLifecycleManager.java:140) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.RegistryLifecycleManager.fireLifecycle(RegistryLifecycleManager.java:111) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.registry.AbstractRegistryBroker.fireLifecycle(AbstractRegistryBroker.java:88) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.registry.MuleRegistryHelper.fireLifecycle(MuleRegistryHelper.java:141) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.MuleContextLifecycleManager$MuleContextLifecycleCallback.onTransition(MuleContextLifecycleManager.java:91) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.MuleContextLifecycleManager$MuleContextLifecycleCallback.onTransition(MuleContextLifecycleManager.java:87) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.MuleContextLifecycleManager.invokePhase(MuleContextLifecycleManager.java:69) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.MuleContextLifecycleManager.fireLifecycle(MuleContextLifecycleManager.java:61) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.DefaultMuleContext.start(DefaultMuleContext.java:294) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.module.launcher.application.DefaultMuleApplication.start(DefaultMuleApplication.java:134) ~[mule-module-launcher-3.7.3.jar:3.7.3]
... 14 more
Caused by: org.mule.api.DefaultMuleException: Address already in use: bind (java.net.BindException)
at org.mule.module.http.internal.listener.DefaultHttpListenerConfig.start(DefaultHttpListenerConfig.java:275) ~[mule-module-http-3.7.3.jar:3.7.3]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_60]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[?:1.7.0_60]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.7.0_60]
at java.lang.reflect.Method.invoke(Method.java:606) ~[?:1.7.0_60]
at org.mule.lifecycle.phases.DefaultLifecyclePhase.applyLifecycle(DefaultLifecyclePhase.java:237) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.RegistryLifecycleCallback.doApplyLifecycle(RegistryLifecycleCallback.java:91) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.RegistryLifecycleCallback.onTransition(RegistryLifecycleCallback.java:67) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.RegistryLifecycleManager.invokePhase(RegistryLifecycleManager.java:140) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.RegistryLifecycleManager.fireLifecycle(RegistryLifecycleManager.java:111) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.registry.AbstractRegistryBroker.fireLifecycle(AbstractRegistryBroker.java:88) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.registry.MuleRegistryHelper.fireLifecycle(MuleRegistryHelper.java:141) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.MuleContextLifecycleManager$MuleContextLifecycleCallback.onTransition(MuleContextLifecycleManager.java:91) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.MuleContextLifecycleManager$MuleContextLifecycleCallback.onTransition(MuleContextLifecycleManager.java:87) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.MuleContextLifecycleManager.invokePhase(MuleContextLifecycleManager.java:69) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.MuleContextLifecycleManager.fireLifecycle(MuleContextLifecycleManager.java:61) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.DefaultMuleContext.start(DefaultMuleContext.java:294) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.module.launcher.application.DefaultMuleApplication.start(DefaultMuleApplication.java:134) ~[mule-module-launcher-3.7.3.jar:3.7.3]
... 14 more
Caused by: java.net.BindException: Address already in use: bind
at sun.nio.ch.Net.bind0(Native Method) ~[?:1.7.0_60]
at sun.nio.ch.Net.bind(Net.java:444) ~[?:1.7.0_60]
at sun.nio.ch.Net.bind(Net.java:436) ~[?:1.7.0_60]
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:214) ~[?:1.7.0_60]
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74) ~[?:1.7.0_60]
at org.glassfish.grizzly.nio.transport.TCPNIOBindingHandler.bindToChannelAndAddress(TCPNIOBindingHandler.java:131) ~[grizzly-framework-2.3.21.jar:2.3.21]
at org.glassfish.grizzly.nio.transport.TCPNIOBindingHandler.bind(TCPNIOBindingHandler.java:88) ~[grizzly-framework-2.3.21.jar:2.3.21]
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.bind(TCPNIOTransport.java:248) ~[grizzly-framework-2.3.21.jar:2.3.21]
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.bind(TCPNIOTransport.java:228) ~[grizzly-framework-2.3.21.jar:2.3.21]
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.bind(TCPNIOTransport.java:219) ~[grizzly-framework-2.3.21.jar:2.3.21]
at org.mule.module.http.internal.listener.grizzly.GrizzlyServer.start(GrizzlyServer.java:41) ~[mule-module-http-3.7.3.jar:3.7.3]
at org.mule.module.http.internal.listener.DefaultHttpListenerConfig.start(DefaultHttpListenerConfig.java:271) ~[mule-module-http-3.7.3.jar:3.7.3]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_60]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[?:1.7.0_60]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.7.0_60]
at java.lang.reflect.Method.invoke(Method.java:606) ~[?:1.7.0_60]
at org.mule.lifecycle.phases.DefaultLifecyclePhase.applyLifecycle(DefaultLifecyclePhase.java:237) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.RegistryLifecycleCallback.doApplyLifecycle(RegistryLifecycleCallback.java:91) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.RegistryLifecycleCallback.onTransition(RegistryLifecycleCallback.java:67) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.RegistryLifecycleManager.invokePhase(RegistryLifecycleManager.java:140) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.RegistryLifecycleManager.fireLifecycle(RegistryLifecycleManager.java:111) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.registry.AbstractRegistryBroker.fireLifecycle(AbstractRegistryBroker.java:88) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.registry.MuleRegistryHelper.fireLifecycle(MuleRegistryHelper.java:141) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.MuleContextLifecycleManager$MuleContextLifecycleCallback.onTransition(MuleContextLifecycleManager.java:91) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.MuleContextLifecycleManager$MuleContextLifecycleCallback.onTransition(MuleContextLifecycleManager.java:87) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.MuleContextLifecycleManager.invokePhase(MuleContextLifecycleManager.java:69) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.lifecycle.MuleContextLifecycleManager.fireLifecycle(MuleContextLifecycleManager.java:61) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.DefaultMuleContext.start(DefaultMuleContext.java:294) ~[mule-core-3.7.3.jar:3.7.3]
at org.mule.module.launcher.application.DefaultMuleApplication.start(DefaultMuleApplication.java:134) ~[mule-module-launcher-3.7.3.jar:3.7.3]
... 14 more

Reason for the issue

The reason for the issue is that the binding address 8081 specified by default for the http configuration might be in use already.

Resolution

In order to resolve this issue change the port for the http server you have configured by default for your application and redeploy the service to Mule server.
I changed it to 9001 an redeployed my service and i was able to deploy the service to the server.

I also made one more change that i changed the context for the http as shown below



So after deployment the following url i used

http://localhost:9001/HelloWorld




Now

Starting with Mulesoft - Anytime Studio

I was going through multiple sites and i found that a lot of firms are recommending Mulesoft as an integration platform. Again as per Gartner it is best product in terms of ipaas, so i thought of starting my R&D in Mulesoft as well.

As a first activity i downloaded the Anytime Studio from

https://www.mulesoft.com/

and tried to install it and i got the first error
It said Java was started but returned exit code=1




I was not sure of the error as i was already having a lot of tools installed in my machine. But then i realized that it is pointing to a location where my java is not installed

C:\ProgramData\Oracle\Java\javapath\javaw.exe

My java was installed in a different directory.

I went to environment variables and checked the PATH variable and then i found that it has an entry like  following: ;C:\ProgramData\Oracle\Java\javapath;

This was wrong entry in the path , I made changes and removed this path and added the correct path for java jdk and i was able to resolve this issue.

Monday, February 29, 2016

Namespace prefix can not be resolved


I was using following function in SOA 12c to get the title for the composite

setCompositeInstanceTitle

However when i set this property it was giving me compilation issue

namespace prefix "oraext" can not be resolved



The reason for this error is that even though we get this functionality in the Jdeveloper by applying patch but it was missing an entry for the prefix.

By default when you use this function it comes as follows

oraext:setCompositeInstanceTitle()

Now you need to make sure that you are adding the prefix oraext explicitly in your BPEL code.

Open your BPEL code

Go to the source code and add following name space in the already existing list of namespace

xmlns: oraext ="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.ExtFunc"

Save the changes and rebuild

Tuesday, February 23, 2016

Generate archive file name manually in SOA Suite



In one of my project i was supposed to read large files, I implemented it using chunk reading in BPEL.

The issue i was facing in this case was the file was not getting archived, this i achieved using file move operation. However the client was very specific for the naming convention of archive file.

I tried to search for some built in commands but was not successful in generating the same so i used the following expression which generate the same file naming convention as Archive by does by default

concat(xp20:format-dateTime(xp20:current-dateTime(),'[Y0001][M01][D01]'),"_",xp20:format-dateTime(xp20:current-dateTime(),'[H01][m01][s01]'),"_",xp20:format-dateTime(xp20:current-dateTime(),'[f001]'))


Friday, February 05, 2016

Distributed Queue and OSB cluster



I tried working in a scenario where in we have a distributed queue in OSB cluster and then i tried to subscribe the queue using a proxy service.
However it didn't worked for me the same way Distributed topic worked(It is creating multiple instances). I need to do some more R&D on this topic before publishing. Let me know if you have any pointers.


Distributed Topic and SOA Cluster



If you are wokring in a SOA Suite cluster with multiple node, you will have to face a lot of issues configuring Distributed topic.

I faced a lot of issue first time , some of the common issues were

1> how to point the distributed topic to multiple targets.
2> For one message multiple subscribers are getting triggered.
3> Messages are going to all the servers.

But all these are just a one time issue. One you know the correct steps you should be able to get it working in a first shot.

In this post we will discuss about the task to be taken care of from admin and developer side.

First step is to create a distributed topic.

first of all it is important to understand that there is a diffence between topic and distributed topic. If you are creating a topic it can just point to one of the managed server , however the distributed topic can be pointed to multiple server.

Steps to be followed for creating a distributed topic are

1> Create JMS servers pointing to individual managed server.



Next create a JMS module

And then a subdeployment

While creating a subdeployment make sure you are targetting it to the JMS server you have created in the previous step.




Now go ahead and create a distributed topic

Go for advance targeting of topic and point it to the sub deployment created.

While creating a distributed topic, one important point is that make sure you are specifying the forwarding policy as Partitioned otherwise the message will be replicated to all the servers.



Now you are good from admin side but a task is required from developer as well that is to add a singleton property in your SOA process.

<binding.jca>
<property name="singleton">true</property>
</binding.jca>

In case you are using OSB as a publisher and subscriber

Make sure you are enabling Quality of service for exactly once.



clustering in OSB is again more confusing so i will write a separate post on my next exercise to make it more clear.



Thursday, February 04, 2016

Configuring Work Manager in SOA OSB 12c



The prioritization of work in weblogic server is based on an execution model which takes into account user/admin defined parameters and actual performance of the server. Weblogic server allows developer to configure work manager to prioritize pending works and improve performance of process. In this exercise we will try to understand how we can configure work managers in SOA/OSB 12c to improve the performance of services.


We will have a look in OSB configuration first as it is straight forward and then we will check on SOA configuration.

WorkManager can be configured in OSB for proxy as well as business services.

Work Manager when configured on Proxy service is used to limit the number of threads running a proxy Service and Work Manager when configured for a Business service used to limit the number of threads that process response from the back end system. It is important to understand that work managers are used to prioritize work unlike throttling which is used to restricts the number of records. So there is a chance that you might loose some data when you have enabled throttling but with work manager you will not loose the data, it will be jsut the prioritization of service will change.

As per oracle documentation

https://docs.oracle.com/middleware/1213/osb/develop/GUID-7A9661AE-6FE5-4A92-A418-694A84D0B0BF.htm#OSBDV89434


The Work Manager (dispatch policy) configuration for a business service should depend on how the business service is invoked. If a proxy service invokes the business service using a service callout, a publish action, or routing with exactly-once QoS (as described in Pipeline Actions), consider using different Work Managers for the proxy service and the business service instead of using the same for both. For the business service Work Manager, configure the Min Thread Constraint property to a small number (1-3) to guarantee an available thread.

Now without going much in to theoretical details we will see how we can configure work manager in OSB 12c. The concept is similar to that of 11g however the screens have changed for osb applications.

So we will first go ahead and login to admin console.

http://host:port/console

Go to Environment-->Work Managers



Create new and create a minimum thread constraint.

Minimum thread constraint ensure that whatever may be the load in the server this minimum number of
threads will be allocated to the service.



Give it a logical name and assign minimum thread

by default it is -1 which mean infinite.



Say next and point it to the server.

Next again go to the work manager and this time create a work manager



Give it some logical name



Next point it to server and finish the wizard


You can now go to your work manager and select the constraint you have defined



Save the changes.

Now once you have the work manager created you just need to attach this work manager to the business process in OSB.

Open up the osb console

http://host:port/sbconsole

Go to your business service

go to transport details

and select the work manager that you have created in the previous steps.



Save the changes and reactivate your session.

For configuring work manager in soa we do not much options.

SOA Services uses a defalt work manager called as wm/SOAWorkManager


YOu can configure your own constraints and update the work managers to use the contraints.



Wednesday, February 03, 2016

Processing large files in Oracle SOA


Recently i was wokring on a requirement to process very large payload. Though now we have MFT feature which we can use to process the files, still we will go ahead and see the three approach to processing it- that is through BPEL,OSB and MFT

For BPEL and OSB it is going to be the same concept that is to use chunking, we will see a demo for BPEL and the same you can replicate in OSB as well.

Before starting i will just clarify that chunking is differnt than debatching. when you debatch your file you actually create multiple instances for the file. However when you chunk read you actually read your whole file in chunk within a single instance. This is a confusion many people have so i just thought of clarifying it. Now with that we will go ahead and see how to create a BPEL process to chunk read the file. Further in chunk read the file does not get deleted once the file is read completely so we will also see how we can achieve that as well.

I will give some details on the implementation however the working code is already provided by oracle at following location.

https://java.net/projects/oraclesoasuite11g/downloads/directory/Adapters/File

Infact i can see that the solution is already provided in details in followin blog

https://technology.amis.nl/2014/05/07/processing-large-files-through-soa-suite-using-synchronous-file-read/

With this sample code and the blog you should be able to create a sample for chunk read easily.

I will just add the extra part of deleting the file from the file polling location.

If you will implement the chunk read you will find that the file does not get deleted post reading the file.

It is because the file can be deleted only outside the loop of chunk read.

File adpater provides feature to delete the file from a location.

Provided you are getting the file name and file location you easily create an adapter to delete the file post chunk reading

Create a simple file adapter with sync read option

Once it is created, a jca file will be created.

Open the jca file and update the changes as shown in the diagram



the class name is oracle.tip.adapter.file.outbound.FileIoInteractionSpec

connect the adapter using an invoke activity.

After connection the process will look like following




Since we have defined logical name and logical directory now pass on the same in the adapter call

Add two properties in the invoke acitivity

jca.file.TargetDirectory

jca.file.TargetFileName



Add an assign activity and copy the file name and directory to the variables



Having said that there are situations where in you will use MFT as well.

I have worked in a situation where in the files were place in some shared drive which was location in a different server.

I had to explicitly use MFT to transfer the file from remote NAS path to local soa server.

Even if we implement a process using MFT we have to make a local copy of the file in the server and a local path is required which is more or less a chunking mechanism (MFT internally uses chunking to process data if you are using MFT adapter).

SO i better thought i will stick to my chunking process and will just use MFT to transfer the file from Shared drive to local path.


Tuesday, January 26, 2016

oracle.mds.exception.MDSException: MDS-01373: unable to retrieve password.



While trying to compile one of my bpel project, i got below error message.



[scac] MDS-01370: MetadataStore configuration for metadata-store-usage "mstore-usage_2" is invalid.
[scac] MDS-00011: unable to create configuration object or MDSInstance due to invalid configuration information: oracle.mds.exception.MDSException: MDS-01373: unable to retrieve password.
[scac] : oracle.mds.config.MDSConfigurationException: MDS-01330: unable to load MDS configuration document
[scac] MDS-01329: unable to load element "persistence-config"
[scac] MDS-01370: MetadataStore configuration for metadata-store-usage "mstore-usage_2" is invalid.
[scac] MDS-00011: unable to create configuration object or MDSInstance due to invalid configuration information: oracle.mds.exception.MDSException: MDS-01373: unable to retrieve password.
[scac] : MDS-01330: unable to load MDS configuration document
[scac] MDS-01329: unable to load element "persistence-config"
[scac] MDS-01370: MetadataStore configuration for metadata-store-usage "mstore-usage_2" is invalid.
[scac] MDS-00011: unable to create configuration object or MDSInstance due to invalid configuration information: oracle.mds.exception.MDSException: MDS-01373: unable to retrieve password.


In order to resolve this issue.

Go to your adf-config.xml file, you can locate it in Jdeveloper



Open the file and add the property name

jdbc-password



Save the changes are rebuilt your code.


Tuesday, January 19, 2016

Create schema for a CSV file with different set of records in multiple lines


We face this issue in most of the integration project.

We get Order information in CSV file which can have header,details , shipping etc information in different line in different format.

Developer often face issues in creating a schema for this kind of file.

In this exercise we will try to create a schema for such kind of CSV file and will then try to process it using soa suite file adapter.

I have following set of CSV file

0,4321432143214321,0316,VISA
Rahi,Arpit,Varthur Hobli,Bangalore,KA,12345,5127691108
Rahi,Arpit,Varthur Hobli,Bangalore,KA,12345,5127691108
Standard,ar@test.com
32779,5,4.72,hard drive,Ramson,2008,hard drive Ramson
30421,16,10.72,RAM,Intel,2005,RAM Intel
32861,11,60.72,Chain,alloy,1829,Ring chain alloy

which needs to be processed.

Here if you can review the file closely you can find that there are four distinct records. So while creating the schema for the csv file you have to ensure that your schema should be able to process this file and it will also take care of the repeating elements.

We will see how we can do this.

We will create a file adapter and will use Define native schema format wizard to create a schema for our schema

I will directly jump to native schema builder.

As soon as you will click on this a gui will come up



say next and update the schema name



Say next and select the default option of delimited file as it is a CSV file



select your csv file and validate it is loaded properly



Say next and choose multiple records are of different type otherwise it will process all the record as a single type.



Say next and give some name to the schema



Say next and validate the delimiter and the end of line



Say next and you will observer it is automatically creating a record for you. However the strange part is that it has created 6 record type instead of 7

In my original csv file i have 7 lines however the record created is 6

The reason being second and third record start with same value and in condition value we should have a unique value.

we will just go ahead with the default configuration by Jdeveloper and later we will change it to see how we can modify this or how we can generalize it for other records as well.

you can go to next page, select the individual record and update the names to some logical name



Again say next, it will generate a default schema for you



Say next and finish the wizard.

create a bpel process to receive the file and deploy the process.


Test the service and you will see a successful instance getting created And you will find the correct payload as you were expecting

<Receive1_Read_InputVariable>
-<part xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="body">
-<Root-Element xmlns="http://TargetNamespace.com/fileService">
-<RECORD1>
<C2>4321432143214321</C2>
<C3>0316</C3>
<C4>VISA</C4>
</RECORD1>
-<RECORD2>
<C2>Arpit</C2>
<C3>Varthur Hobli</C3>
<C4>Bangalore</C4>
<C5>KA</C5>
<C6>12345</C6>
<C7>5127691108</C7>
</RECORD2>
-<RECORD2>
<C2>Arpit</C2>
<C3>Varthur Hobli</C3>
<C4>Bangalore</C4>
<C5>KA</C5>
<C6>12345</C6>
<C7>5127691108</C7>
</RECORD2>
-<RECORD3>
<C2>ar@test.com</C2>
</RECORD3>
-<RECORD4>
<C2>5</C2>
<C3>4.72</C3>
<C4>hard drive</C4>
<C5>Ramson</C5>
<C6>2008</C6>
<C7>hard drive Ramson</C7>
</RECORD4>
-<RECORD5>
<C2>16</C2>
<C3>10.72</C3>
<C4>RAM</C4>
<C5>Intel</C5>
<C6>2005</C6>
<C7>RAM Intel</C7>
</RECORD5>
-<RECORD6>
<C2>11</C2>
<C3>60.72</C3>
<C4>Chain</C4>
<C5>alloy</C5>
<C6>1829</C6>
<C7>Ring chain alloy</C7>
</RECORD6>
</Root-Element>
</part>
</Receive1_Read_InputVariable>


however there is lot of things that we need to understand here. We can observer that the first value in every record is missing.

We will try to analyse it with the schema that got generated by default

<?xml version = '1.0' encoding = 'UTF-8'?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:nxsd="http://xmlns.oracle.com/pcbpel/nxsd" xmlns:tns="http://TargetNamespace.com/fileService" targetNamespace="http://TargetNamespace.com/fileService" elementFormDefault="qualified" attributeFormDefault="unqualified" nxsd:version="NXSD" nxsd:stream="chars" nxsd:encoding="US-ASCII">


<xsd:element name="Root-Element">
<xsd:complexType>
<xsd:choice minOccurs="1" maxOccurs="unbounded" nxsd:choiceCondition="terminated" nxsd:terminatedBy=",">
<xsd:element name="RECORD1" nxsd:conditionValue="0">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="C2" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="," nxsd:quotedBy="""/>
<xsd:element name="C3" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="," nxsd:quotedBy="""/>
<xsd:element name="C4" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="${eol}" nxsd:quotedBy="""/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="RECORD2" nxsd:conditionValue="Rahi">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="C2" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="," nxsd:quotedBy="""/>
<xsd:element name="C3" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="," nxsd:quotedBy="""/>
<xsd:element name="C4" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="," nxsd:quotedBy="""/>
<xsd:element name="C5" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="," nxsd:quotedBy="""/>
<xsd:element name="C6" type="xsd:int" nxsd:style="terminated" nxsd:terminatedBy="," nxsd:quotedBy="""/>
<xsd:element name="C7" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="${eol}" nxsd:quotedBy="""/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="RECORD3" nxsd:conditionValue="Standard">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="C2" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="${eol}" nxsd:quotedBy="""/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="RECORD4" nxsd:conditionValue="32779">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="C2" type="xsd:int" nxsd:style="terminated" nxsd:terminatedBy="," nxsd:quotedBy="""/>
<xsd:element name="C3" type="xsd:decimal" nxsd:style="terminated" nxsd:terminatedBy="," nxsd:quotedBy="""/>
<xsd:element name="C4" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="," nxsd:quotedBy="""/>
<xsd:element name="C5" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="," nxsd:quotedBy="""/>
<xsd:element name="C6" type="xsd:int" nxsd:style="terminated" nxsd:terminatedBy="," nxsd:quotedBy="""/>
<xsd:element name="C7" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="${eol}" nxsd:quotedBy="""/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="RECORD5" nxsd:conditionValue="30421">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="C2" type="xsd:int" nxsd:style="terminated" nxsd:terminatedBy="," nxsd:quotedBy="""/>
<xsd:element name="C3" type="xsd:decimal" nxsd:style="terminated" nxsd:terminatedBy="," nxsd:quotedBy="""/>
<xsd:element name="C4" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="," nxsd:quotedBy="""/>
<xsd:element name="C5" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="," nxsd:quotedBy="""/>
<xsd:element name="C6" type="xsd:int" nxsd:style="terminated" nxsd:terminatedBy="," nxsd:quotedBy="""/>
<xsd:element name="C7" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="${eol}" nxsd:quotedBy="""/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="RECORD6" nxsd:conditionValue="32861">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="C2" type="xsd:int" nxsd:style="terminated" nxsd:terminatedBy="," nxsd:quotedBy="""/>
<xsd:element name="C3" type="xsd:decimal" nxsd:style="terminated" nxsd:terminatedBy="," nxsd:quotedBy="""/>
<xsd:element name="C4" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="," nxsd:quotedBy="""/>
<xsd:element name="C5" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="," nxsd:quotedBy="""/>
<xsd:element name="C6" type="xsd:int" nxsd:style="terminated" nxsd:terminatedBy="," nxsd:quotedBy="""/>
<xsd:element name="C7" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="${eol}" nxsd:quotedBy="""/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>


You can observe here that for every record element there is a conditional value which is nothing but the first column of the record.
So ideally we were expecting all the records but some how we got the record will one less value.

We will now try to see what all changes we can do to get all the records.

Monday, January 18, 2016

Generate unique id for multiple order lines


More than often we come across a requirement that a unique order line should only be processed.

That essentially mean you can have multiple parameters in your order line and you want to pick record with a unique combination of some attribute in your order line data. this will be more clear with an example and then subsequent solution for the issue.

This we will achieve using two XSLT function

XSLT key function which returns a node-set from the document, using the index specified by an element.

XSLT generate-id() Function which returns a string value that uniquely identifies a specified node.

If the node-set specified is empty, an empty string is returned. If you omit the node-set parameter, it defaults to the current node.

You can get more idea on the same from w3 schools

http://www.w3schools.com/xsl/func_generateid.asp
http://www.w3schools.com/xsl/func_key.asp

Now we will see in this example how we can use these two function to process unique order line.

First you should define a key, i.e. let suppose you want to process an order with a unique combination of account number and po number. In that case you will first define a key as below



Here xpath for parameter can be the path in your xml where account number and po number can be traversed

e.g if you have following xpath valid

/PO/ListofPO/AccontNumber
/PO/ListofPO/PoNumber

so your match parameter will be /PO/ListofPO

Obviously the namespace has to be there.

Now you got an idea on how to generate a key for a combination of parameter.

Lets generate a unique if for this key

/PO/ListofPO/PODetails[generate-id()=generate-id(key('Order',concat(ns0:AccountNumber,",",ns0:PoNumber))[1])]

Now what this mean is the processing will happend for the PODetails which has a unique combination of AccountNumber and PoNumber


oracle.j2ee.ws.client.jaxws.JRFSOAPFaultException


This is a very common issue when you try to access Siebel or Magento web services from Oracle SOA Suite.

The reason for this error is that in SOA when the external magento or siebel web services are called.

SOA adds additional header information which these backend system do not process.

wsa:TO
wsa:Action
ReplyTo
FaultTo

In order to resolve this issue, all you need to do is to remove the additional header information from the SOA

Use the following property in the composite.xml for the component which is getting called

oracle.soa.ws.outbound.omitWSA = true

This will suppress all the header information for the outgoing call from SOA.


I used this property for the component under binding information in my composite.xml

Redeployed the process and i was able to resolve the issue.


You might also face similar kind of issue while getting the response back.


If you want to suppress the header information from response you will have to use following property in composite.xml

oracle.soa.addressing.response.enabled = false



For each activity in BPEL 2.0


With BPEL 2.0 a lot of new changes has come.

Earlier if you had to implement a loop you will use flowN or while loop, however with BPEL 2.0 we now have a for each activity and it is very easy to use.

Let suppose you have a xml schema

<xsd:element name="CompleteOrder">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="OrderNumber" minOccurs="1" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Order" type="xsd:string" nxsd:style="terminated" nxsd:terminatedBy="${eol}" nxsd:quotedBy="""/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>


You want to call an adapter for every order.

you can do this very easily using a for each activity.

Drag and drop a for each activity in the process.

Specify the counter name and copy it as this is the counter variable name that needs to be used inside a process to loop for element



Now go to counter Value tab and specify the initial counter as 1

Again for Final value get the count of OrderNumber as shown in the diagram.

As you can see from the schmea OrderNumber is the repeating element so count() is used to get the final number.



NOw we are almost done ,

Only thing required is to use the counter variable during your assign activity .


you have to use it in the same as you used to do in case of a loop.

For the repeating node you have to use following syntax

RepeatingNode[$ForeachCounter]


As you can see ForeachCounter is the same variable we have defined in the very first step.

So a normal assign will have and entry like this.




your assign should be within the scope of for each



Group and Summarize data in XSLT


I was trying to process an order data which has multiple item. My requirement was to group and summarize the data.

I have following input

<soas:Items>
<soas:Item >
<soas:SKU>32779</soas:SKU>
<soas:Quantity>5</soas:Quantity>
<soas:UnitPrice>10</soas:UnitPrice>
</soas:Item>
<soas:Item >
<soas:SKU>30421</soas:SKU>
<soas:Quantity>2</soas:Quantity>
<soas:UnitPrice>10</soas:UnitPrice>
</soas:Item>
<soas:Item >
<soas:SKU>32861</soas:SKU>
<soas:Quantity>1</soas:Quantity>
<soas:UnitPrice>60</soas:UnitPrice>
</soas:Item>
<soas:Items>


I want the summary of all item amount that is summation for price*quanity of all the items

Summary = (Price*Quantity+Price*Quantity+Price*Quantity)=130

I tried to implement it in XSLT 2.0 but that didn't work for me.

I tried it in XSLT 1.1 using XSLT call template and this worked for me.

I tried to capture the value in Amount element, I used the following code

<tns:Amount>
<xsl:call-template name="sum">
<xsl:with-param name="nodes" select="/ns0:Order/ns0:Items/ns0:Item"/>
</xsl:call-template>
</tns:Amount>


<xsl:template name="sum">
<xsl:param name="nodes"/>
<xsl:param name="sum" select="0"/>
<xsl:variable name="current" select="$nodes[1]"/>
<xsl:if test="$current">
<xsl:call-template name="sum">
<xsl:with-param name="nodes" select="$nodes[position() > 1]"/>
<xsl:with-param name="sum" select="$sum + $current/ns0:UnitPrice * $current/ns0:Quantity"/>
</xsl:call-template>
</xsl:if>
<xsl:if test="not($current)">
<xsl:value-of select="$sum"/>
</xsl:if>
</xsl:template>