BizTalk Business Rules Engine - Repeating Elements - biztalk

I'm trying to create what I think should be a relatively simple business rule to operate over repeating elements in an XML schema.
Consider the following XML snippet (this is simplified with namespaces removed, for readability):
<Root>
<AllAccounts>
<Account id="1" currentPayment="10.00" arrearsAmount="25.00">
<AllCustomers>
<Customer id="20" primary="true" canSelfServe="false" />
<Customer id="21" primary="false" canSelfServe="false" />
</AllCustomers>
</Account>
<Account id="2" currentPayment="10.00" arrearsAmount="15.00">
<AllCustomers>
<Customer id="30" primary="true" canSelfServe="false" />
<Customer id="31" primary="false" canSelfServe="false" />
</AllCustomers>
</AllAccounts>
</Root>
What I want to do is to have two rules:
Set /Root/AllAccounts/Account[x]/AllCustomers/Customer[primary='true']/canSelfServe
= true IF arrearsAmount < currentPayment
Set /Root/AllAccounts/Account[x]/AllCustoemrs/Customer[primary='true']/canSelfServer
= false IF arrearsAmount >= currentPayment
Where [x] is 0...number of /Root/AllAccounts/Account records present in the XML.
I've tried two simple rules for this, and each rule seems to fire x * x times, where x is the number of Account records in the XML. I only want each rule to fire once for each Account record.
Any help greatly appreciated!
Thanks
Andrew

Make sure that the rules have the same Priority, just in case (I had issues with priorities before). I've also saw that at the Rules level, there is a property called maximum Execution Loop Depth, which assigns how many times can a rule be reevaluated. Try to put 1 there, if you're sure that your rules should only be evaluated once per payload. I hope this helps.

Check your predicate. The rule fires once for each matching combo of fields used in the predicate.

Related

Whats the relation between load and for?

I am trying tsung for the first time, however, I need some clarification.
I am using load tag as:
<load>
<arrivalphase phase="1" duration="1" unit="minute">
<users maxnumber="100000" interarrival="0.01" unit="second"/>
</arrivalphase>
</load>
But, how would the for loop below works ?:
<sessions>
<session name="root" probability="100" type="ts_http">
<for from="1" to="2" var="i">
<request>
<http url="/test/counter" method="POST" contents="bla=blu&name=glop">
</http>
</request>
</for>
</session>
What I thought is that the loop will count from 1 to 2, thus, sending only two requests, however, when I run the xml file, I got hundred of requests! Does this mean that each user in arrivalphase will send two requests as in the for loop above?
Can someone explain, what's the relation between the for tag and load tag as in the above example?
Your analysis is right , during the first 1 minute of the test , you created 100 users per second,each user will send two requests as in the for loop above。
The load define tsung generate rules of the user, the session define every user needs to perform logic.

One API proxy calling two different target endpoints

i have just started working with Apigee.
I want to create one API proxy which will call two target endpoints based on 'if' condition.
i have created an API and added resources to it but the problem is in this case i am getting two API's .
If thetype='abc' target point should be target1
if thetype='xyz' target point should be target2
Can anyone please tell me how to proceed with it ?
Check out the answer to this question. The details of finding the RouteRules is listed there. The ProxyEndpoint documentation will also be helpful.
You can accomplish what you are attempting using this code:
<RouteRule name="routeToTarget1">
<Condition>thetype == "abc"</Condition>
<TargetEndpoint>target1</TargetEndpoint>
</RouteRule>
<RouteRule name="routeToTarget2">
<Condition>thetype == "xyz"</Condition>
<TargetEndpoint>target2</TargetEndpoint>
</RouteRule>
These RouteRules will be evaluated in order.
Note that you probably want the bottom RouteRule to have no condition, which means it will always match. What happens when thetype does not equal "abc" or "xyz"? Assuming target1 is the default, your code would look like this:
<RouteRule name="routeToTarget2">
<Condition>thetype == "xyz"</Condition>
<TargetEndpoint>target2</TargetEndpoint>
</RouteRule>
<RouteRule name="routeToTarget1">
<TargetEndpoint>target1</TargetEndpoint>
</RouteRule>
If you are using the API Proxy Editor UI, then you can do the following:
(1) Choose New / New Resource from the API Proxy Editor toolbar.
You will then see this:
(2) For the input field, Optional Target URL, enter the target URL that corresponds to that resource.
This tool will then generate both a conditional flow for that resource to which you can optionally attach resource-specific policies.
This tool will also add the needed route rule, and your generated XML will look like this:
<ProxyEndpoint name="default">
<RouteRule name="Resource-1">
<Condition>(proxy.pathsuffix MatchesPath "/someResource") and (request.verb = "GET")</Condition>
<HTTPTargetConnection>
<URL>http://myAlternateEndpoint</URL>
</HTTPTargetConnection>
</RouteRule>
....

How to handle Apigee error case when query parameter checking in proxy

I have the following. The parameter "g" is allowed to be "on" or "off", otherwise go to an error policy. However, the exception case is never called. Instead, the "on" case is called if something that is not "on" or "off" is passed as "g". Why is that? Or, is there a better way of expressing this?
<PreFlow name="PreFlow">
<Request>
<Step>
<Condition>message.queryparam.g := "on"</Condition>
<Name>GOn</Name>
</Step>
<Step>
<Condition>message.queryparam.g := "off"</Condition>
<Name>GOff</Name>
</Step>
<Step>
<Condition>!((message.queryparam.g := "off") || (message.queryparam.g := "on"))</Condition>
<Name>GError</Name>
</Step>
</Request>
I just tested your conditions and they work properly. If the request has the following query parameter values:
g=on or g=ON, the GOn policy will execute.
g=off or g=OFF, the GOff policy will execute.
g={anythingelse}, the GError policy will execute.
The := operator is the equals case-insensitive operator. How are you determining that the conditions are not working? Using your example, I made each of the policies a RaiseFault with a different fault response payload. This allowed me to verify which policy was executed depending on the value of g.
I agree with Michael, the code as shown is correct.
Thinking about possible issues that could cause this code to not work as expected:
Make sure that the names are correct inside your GOn, GOff, and GError policies. (If you are working offline, the name of the file has nothing to do with which policy gets called.) For example, the outer element of the GOn policy should look something like
<AssignMessage name="GOn">
If GOn uses AssignMessage to modify message, you might blow away the g query parameter during a step, and your later checks might fail. If you are modifying the message, store message.queryparam.g into a different variable before you do your checks.
I would use the trace tool and a tool like Postman to see what is happening for each request. The trace should tell you the variables that have been checked and their values, and you might be able to see where you are going wrong.
If you have multiple conditional checks try using javascritp.In the java script check the various conditions and set flag.And in the flow based on the value of flag execute the required policy.But for the above instance ,as Michael pointed out , the conditions should work as expected.

Voiceglue Logger says Maximum loop count exceeded. There is probably an infinite loop of in your VXML document

Can Any please explain why this is happening. what are the possibilities of errors that are been counted as I have set maxerrorcount = 3
EROR OPEN_VXI luke---- callid=[68] |1098905920|68|CRITICAL|com.vocalocity.vxi|216|VXIinterpreterRun: Maximum loop count exceeded. There is probably an infinite loop of in your VXML document.|URL
Please let me know if any further details are required.
Perhaps, "infinite loop" means to call same form again and again,
And it was not inserted caller input process(menu, field and record form) in this loop.
For example
<form id="errorForm"><!-- Loop Start -->
<block>
<!-- something -->
</block>
<block>
<goto next="errorForm" /><!-- Loop End -->
</block>
</form>
Bladean's answer is probably the correct one. There is an alternate possibility. If an application is structured has looping logic that cycles through the same form or page as it processes data (e.g. a long list), you can trigger these types of checks. I have had to increase a similar loop counter, for some applications, on another platform.
Voice browser all have infinte loop detection to save them from pitfalls .
It could be something as simple as the "goto where I am coming from example" within the same VXML document example provided here by Bladean Mericle .
It could be burried deeper in a global catch that routes calls to a catch all sub application which in turn bring the flow back to the originating dialog .
Definetely Infinite Loops will never work in VXML .

SCORM multiple rollup action

How do I specify a multiple roll up action for example. Based on success status of any one SCO I want the overall status of the course to be satisfied and similarly based on the completion status of any of the SCO, I want the completion status of the overall course to be completed. I tried doing it by specifying 2 rollup rules but testing on scorm.com is not giving the expected result. Any clues?
<imsss:rollupRules objectiveMeasureWeight="1">
<imsss:rollupRule childActivitySet="any">
<imsss:rollupConditions conditionCombination="any">
<imsss:rollupCondition operator="noOp" condition="completed" />
</imsss:rollupConditions>
<imsss:rollupAction action="completed" />
</imsss:rollupRule>
<imsss:rollupRule childActivitySet="any">
<imsss:rollupConditions conditionCombination="any">
<imsss:rollupCondition operator="noOp" condition="satisfied" />
</imsss:rollupConditions>
<imsss:rollupAction action="satisfied" />
</imsss:rollupRule>
</imsss:rollupRules>
This is what I have set but this doesnot seem to work. Can somebody point out whats wrong?
To clarify, do you mean that the status of one particular SCO controls the rolled up status? Or, do you mean that if any SCO achieves a status then the parent should also attain that status?
If it is the former, you want to just mark all of the other SCOs as not contributing to rollup. See the Post Test Rollup golf example.
If it is the later, then you will want a rollup rule on the parent that says "if any completed/satisfied then completed/satisfied".
You are on the right track by having two separate rollup rules for the separate status rollups. In fact, you need a separate rollup rule for each individual status...i.e. a rule for incomplete, a rule for completed, a rule for satisfied and a rule for not satisfied.

Resources