forEach loop in BPEL (WSO2 BPS) - wso2

I am not able to figure out the root cause for the problem, why the forEach loop is not working,
<bpel:forEach name="eachMarket" parallel="no" counterName="marketCounter">
<bpel:startCounterValue>1</bpel:startCounterValue>
<bpel:finalCounterValue>count($input.payload/tns:DCTResponse/tns:DCTIDs/tns:DCTID)</bpel:finalCounterValue>
<bpel:scope>
<bpel:assign>
<bpel:copy ignoreMissingFromData="yes" insertMissingToData="yes">
<bpel:from>$input.payload/tns:DCTResponse/tns:DCTIDs/tns:DCTID[round($marketCounter)]/tns:DEFTYPE</bpel:from>
<bpel:to>$OrderParameterPLRequest.parameters/ns:DCTResponse/ns:DCTIDs/ns:DCTID[round($marketCounter)]/ns:DEFTYPE</bpel:to>
</bpel:copy>
<bpel:copy ignoreMissingFromData="yes" insertMissingToData="yes">
<bpel:from>$input.payload/tns:DCTResponse/tns:DCTIDs/tns:DCTID[round($marketCounter)]/tns:MarketName</bpel:from>
<bpel:to>$OrderParameterPLRequest.parameters/ns:DCTResponse/ns:DCTIDs/ns:DCTID[round($marketCounter)]/ns:MarketName</bpel:to>
</bpel:copy>
<bpel:copy ignoreMissingFromData="yes" insertMissingToData="yes">
<bpel:from>$input.payload/tns:DCTResponse/tns:DCTIDs/tns:DCTID[round($marketCounter)]/tns:DCTID</bpel:from>
<bpel:to>$OrderParameterPLRequest.parameters/ns:DCTResponse/ns:DCTIDs/ns:DCTID[round($marketCounter)]/ns:DCTID</bpel:to>
</bpel:copy>
</bpel:assign>
</bpel:scope>
</bpel:forEach>
<bpel:forEach name="eachParameter" parallel="no" counterName="parameterCounter">
<bpel:startCounterValue>1</bpel:startCounterValue>
<bpel:finalCounterValue>count($input.payload/tns:DCTResponse/tns:AdditionalParamters/tns:Parameter)</bpel:finalCounterValue>
<bpel:scope name="parameterScope">
<bpel:assign>
<bpel:copy ignoreMissingFromData="yes" insertMissingToData="yes">
<bpel:from>$input.payload/tns:DCTResponse/tns:AdditionalParamters/tns:Parameter[$parameterCounter]/tns:Name</bpel:from>
<bpel:to>$OrderParameterPLRequest.parameters/ns:DCTResponse/ns:AdditionalParamters/ns:Parameter[$parameterCounter]/ns:Name</bpel:to>
</bpel:copy>
<bpel:copy ignoreMissingFromData="yes" insertMissingToData="yes">
<bpel:from>$input.payload/tns:DCTResponse/tns:AdditionalParamters/tns:Parameter[$parameterCounter]/tns:Value</bpel:from>
<bpel:to>$OrderParameterPLRequest.parameters/ns:DCTResponse/ns:AdditionalParamters/ns:Parameter[$parameterCounter]/ns:Value</bpel:to>
</bpel:copy>
</bpel:assign>
</bpel:scope>
</bpel:forEach>
Input will contain multiple Ids,
<p:DCTIDs>
<p:DCTID>
<p:DEFTYPE>acvinclis</p:DEFTYPE>
<p:MarketName>pectoreflammas</p:MarketName>
<p:DCTID>3</p:DCTID>
</p:DCTID>
<p:DCTID>
<p:DEFTYPE>acvinclis</p:DEFTYPE>
<p:MarketName>pectoreflammas</p:MarketName>
<p:DCTID>3</p:DCTID>
</p:DCTID>
<p:DCTID>
<p:DEFTYPE>acvinclis</p:DEFTYPE>
<p:MarketName>pectoreflammas</p:MarketName>
<p:DCTID>3</p:DCTID>
</p:DCTID>
</p:DCTIDs>
Error message:
faultExplanation={http://docs.oasis-open.org/wsbpel/2.0/process/executable}selectionFailure: No results for expression: '$OrderParameterPLRequest.parameters/ns:DCTResponse/ns:DCTIDs/ns:DCTID[round($marketCounter)]/ns:DEFTYPE' against '

This question is probably not relevant for the original poster anymore, but I wanted to include an answer in case anybody else has the same problem.
If you want to get the DEFTYPE of the DCTID at position $Counter, use the following XPath:
($input.payload/tns:DCTResponse/tns:DCTIDs/tns:DCTID)[position() = $Counter]/tns:DEFTYPE
Two things are important here:
Put parentheses around the entire expression up to DTCID. For the reason why, see https://stackoverflow.com/a/8336922/5986352
While [1], [2], etc. will work, [$Counter] will not work. Instead, use [position() = $Counter]. You can also use position() to perform some more complex queries, e.g., [position() < 3] in order to select the first two nodes from a certain set.

Related

How to exclude method in coverlet coverage report?

How can I exclude a method from code coverage reporting using coverlet and reportgenerator. Excluding entire namespaces in .runsettings works as expected but using [ExcludeFromCodeCoverage] attribute excludes the entire file instead of only the targeted method. See Comments below for what I've tried in .runsettings.
relevant .runsettings lines:
<DataCollectionRunSettings>
<DataCollectors>
<DataCollector>
<Configuration>
<Format>lcov</Format>
<Include>[*]*</Include>
<Exclude>
<!-- excluded namespaces -->
</Exclude>
<!-- excludes entire file from coverage -->
<ExcludeByAttribute>Obsolete, GeneratedCodeAttribute, CompilerGeneratedAttribute,ExcludeFromCodeCoverage</ExcludeByAttribute>
<!-- included & reported as uncovered -->
<ExcludeByAttribute> ExcludeFromCodeCoverageAttribute </ExcludeByAttribute>
<SingleHit>true</SingleHit>
<UseSourceLink>true</UseSourceLink>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<!-- included and reported as uncovered -->
<CodeCoverage>
<Attributes>
<Exclude>
<Attribute> ^System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute$</Attribute>
</Exclude>
</Attributes>
</CodeCoverage>
</Configuration>
</DataCollector>
</DataCollectors>
</DataCollectionRunSettings>
UPDATE: It seems to have been a recently resolved issue with coverlet. Updating resolved the issue. https://github.com/coverlet-coverage/coverlet/issues/809
Just apply [ExcludeFromCodeCoverage] on the method instead of the class.

BPEL Assign expression count(nodes) returns double

Using wso2bps-3.5.1
The count() of nodes in my Assign activity is assigned to an Integer typed element (verifyTerminationRequest/connections):
<bpel:copy>
<bpel:from expressionLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0">
<![CDATA[count($closeAccountResponse.closeAccountResponsePart/xclac:accountConnections/xcom:accountConnection)]]>
</bpel:from>
<bpel:to part="parameters" variable="verifyTerminationRequest">
<bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[wvete:verifyTerminationRequestMessage[1]/wvete:connections]]></bpel:query>
</bpel:to>
</bpel:copy>
For some reason the resulting message looks like this:
<verifyTerminationRequest xmlns="http://seb.se/ops/ica/vete/wsdl">
<ax2410:verifyTerminationRequestMessage xmlns:ax2410="http://seb.se/ops/ica/vete/wsdl">
<ax2410:connections>2.0</ax2410:connections>
</ax2410:verifyTerminationRequestMessage>
</verifyTerminationRequest>
And verifyTerminationRequestMessage/connections = 2.0 throws an exception:
Fault Name {http://seb.se/ops/ica/vete/wsdl}UnknownFault
Fault Data
<?xml version="1.0" encoding="UTF-8"?><message>
<Fault>
<faultcode>soapenv:Server</faultcode>
<faultstring>java.lang.NumberFormatException: For input string: "2.0"</faultstring>
</Fault>
</message>
Error Line 356
Why?
I've tried with round(count(...)) with no success.
try number function - number(count()) it works for me.

MapForce - Add dayTimeDuration to dayTimeDuration

I am trying to use mapforce to generate an xslt 2.0 file. The mapping is adding 2 dayTimeDuration elements, doing so results in the following error;
No match for core.add(xs:dayTimeDuration, xs:dayTimeDuration). Check argument types.
Supported: +(xs:double, xs:double) -> xs:double
I thought that xslt 2.0 supported adding 2 dayTimeDurations. Is there a way of doing this using mapforce?
Cheers
Stew
Had almost the same problem, first tried to add functx-library but saw it creates absolute path in the generated xslt2-code, which isn't very good.
Well, turns out you can implement that function, but first you have to do some modifications...
Find your Mapforce installation directory, and MapForceLibraries -subdirectory. From that open the "core.mff", and find
<group name="math functions">
<component name="add" growable="true" growablebasename="value">
<sources>
<datapoint name="value1" type="xs:decimal"/>
<datapoint name="value2" type="xs:decimal"/>
</sources>
<targets>
<datapoint name="result" type="xs:decimal"/>
</targets>
As you can seem the "sources" and "targets" elements seems to define the in- and out data types. As it is, they have only implemented "add"-function for "xs:decimal". You can copy/paste this component, then rename it and give new in- out- data types, in your case they are both "xs:dayTimeDuration". Note that there are implementations for each supported language, but you can omit those that are not needed. Here's
what should work:
<component name="addDayTimeDuration" growable="true" growablebasename="value">
<sources>
<datapoint name="value1" type="xs:dayTimeDuration"/>
<datapoint name="value2" type="xs:dayTimeDuration"/>
</sources>
<targets>
<datapoint name="result" type="xs:dayTimeDuration"/>
</targets>
<implementations>
<implementation language="xslt">
<operator value="+"/>
</implementation>
<implementation language="xslt2">
<operator value="+"/>
</implementation>
<implementation language="builtin">
<function name="Core_Add"/>
</implementation>
</implementations>
<description>
<short>result = value1 + value2</short>
<long>Result is the dayTimeDuration value of adding value1 and value2.</long>
</description>
</component>
Your new function should now appear in the "math functions" and should be good to use.
After contacting Altova (the makers of MapForce);
While XPath 2 does offer a subtract-dayTimeDurations operation, this is not presently offered as a function inside MapForce.

Not able pass array value in wso2 BPS

My Input Request is:
<body>
<p:UpdateEntID xmlns:p="http://tempuri.org/">
<!--1 or more occurrences-->
<xs:OldID xmlns:xs="http://tempuri.org/">GenreID_002</xs:OldID>
<xs:OldID xmlns:xs="http://tempuri.org/">GenreID_0021</xs:OldID>
<!--Exactly 1 occurrence-->
<xs:NewID xmlns:xs="http://tempuri.org/">GenreID_001</xs:NewID>
</p:UpdateEntID>
</body>
How to assign both the input values i.e OldID to wsdl's Input variable EquivalentEntPLRequest?
My assign is:
<bpel:assign validate="no" name="AssignInputForUpdateID">
<bpel:copy>
<bpel:from>
<bpel:literal>
<ns0:UpdateEntID xmlns:ns0="http://tempuri.org/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><ns0:newid>ns0:newid</ns0:newid>
<ns0:oldid>ns0:oldid</ns0:oldid>
</ns0:UpdateEntID>
</bpel:literal>
</bpel:from>
<bpel:to variable="EquivalentEntPLRequest" part="parameters"></bpel:to>
</bpel:copy>
<bpel:copy>
<bpel:from part="parameters" variable="clientRequest6">
<bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[tns:NewID]]></bpel:query>
</bpel:from>
<bpel:to part="parameters" variable="EquivalentEntPLRequest">
<bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0">
<![CDATA[ns3:newid]]>
</bpel:query>
</bpel:to>
</bpel:copy>
<bpel:copy>
<bpel:from part="parameters" variable="clientRequest6">
<bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[tns:OldID[1]]]></bpel:query>
</bpel:from>
<bpel:to part="parameters" variable="EquivalentEntPLRequest">
<bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[ns3:oldid[1]]]></bpel:query>
</bpel:to>
</bpel:copy>
</bpel:assign>
By the above assign i am able to map single value of request to single value of response.So how can i map multiple inputs of bpel input to multiple input of wsdl input?Thanks in advance

How to traverse a list of ints in a BPEL process

I am building a BPEL process in Netbeans 6.8 and I invoke a Web Service that returns a list of ints.
<xs:complexType name="getHotelsResponse">
<xs:sequence>
<xs:element name="return" type="xs:int" minOccurs="0" maxOccurs="unbounded"></xs:element>
</xs:sequence>
</xs:complexType>
I want (if possible - not sure anymore...) to iterate through all those ints and invoke a different Web Service for each one of them.
I tried using a ForEach activity, but I can't figure out the usage for my case.
It requires a Start Value and an End Value (if I could somehow get how many ints I got back) but even then inside the ForEach activity if say I put an Assign activity how do I get the current element of the list in each loop?
I used following BPEL snippet to concat the content of a list in to a comma separated string.
You can use the same code with an invoke to call external service.
<bpel:forEach parallel="no" counterName="Counter" name="ForEach">
<bpel:startCounterValue>
<![CDATA[1]]>
</bpel:startCounterValue>
<bpel:finalCounterValue><![CDATA[count($input.payload/tns:return)]]></bpel:finalCounterValue>
<bpel:scope>
<bpel:assign validate="no" name="AppendItem">
<bpel:copy>
<bpel:from>
<![CDATA[concat($Response, $input.payload/tns:return[round($Counter)], ", ")]]>
</bpel:from>
<bpel:to variable="Response"></bpel:to>
</bpel:copy>
</bpel:assign>
</bpel:scope>
</bpel:forEach>
You can get the count of elements from the following XPath
count($input.payload/tns:return)
You can access value of the i th element using the following XPath
$input.payload/tns:return[round($Counter)]
You may get rid of the round() function, but I had to use to get rid of an issue in Apache ODE.