The rsb:call keyword is used to call RSSBus operations. RSSBus operations can be local operations that are installed along with connector assemblies (dll's in bin folder of the RSSBus application); they can be rsb:scripts on a remote machine that are called over HTTP; they can be an RSS feed anywhere on the internet; and they can be calls to other services existing on the same machine.
The scope of rsb:call is executed for every item generated by the call. Within the scope of rsb:call you are allowed to inspect and modify the attributes in the item returned from the call. You can then use these attributes to call another RSSBus operation, thus forming an operation pipeline, or you simply push out the item as response of the call.
Specifying Input to an Operation
There are 3 ways to provide input to a call:
- The default item: If input item is not specified (see the in parameter), the default item is used as input for the called operation. In such a case the called operation would read input vales from the default item. The following example shows how you can set values in the default item so that they are processed by the called operation.
<rsb:set attr="mask" value="*.txt"/> <rsb:set attr="path" value="C:\\"/> <rsb:call op="fileListDir"> ... </rsb:call>
- An explicit "in" item: You may explicitly specify the item or items you want to use as input to an operation using the "in" parameter. If you choose to do so the default item is no longer used and the input values are read from the input items specified and the query string parameters. In this case, as before, the query string attributes take precedence over input items.
<rsb:set attr="mask" value="*.* -- Will be ignored --"/> <rsb:set attr="myinput.mask" value="*.txt"/> <rsb:set attr="myinput.path" value="C:\\"/> <rsb:call op="fileListDir" in="myinput"> ... </rsb:call>
- The query string of the call itself: Another way of specifying input to an operation is to use the query string notation, where the operation name is succeeded by a list of attributes. If this scheme is chosen, the attributes specified as part of the query string are given preference. If there is a name clash between attributes specified in the query string and those in the default item the ones in the query string are preferred. However, the other attributes of the default item are still accessible.
<rsb:set attr="myinput.mask" value="*.txt -- will be overridden --"/> <rsb:set attr="myinput.path" value="C:\\"/> <rsb:call op="fileListDir?mask=*.rsb" in="myinput"> ... </rsb>
The Output Item Stack and the Default Item
The RSSBus Engine internally has a stack of items on which a new item is pushed each time a rsb:call is encountered. We refer to the item on the top of this stack as the default item (that is the item that is used when item name is not explicitly specified). The default item is where the called operation will write attributes and is also the one that is pushed out to the output by rsb:push. You can refer to this default item as _ , or _out[n] (where n is the depth of the stack), or by your chosen name specified in the "out" parameter.
Let's look at an example script..
In the example above we see how items are pushed to the top of the stack with each call and how the default item changes within scope of each call. There are a few things that might not be immediately obvious from the example above:<rsb:call op="operation1"> The default item here is _out1 A push here would push the attributes from _out1 The input item used to call operation2 is also _out1 <rsb:call op="operation2"> The default item here is _out2 A push here will push the attributes from _out2 If there was another rsb:call here the input item used would be _out2 _out2 is swept clean here for the next iteration </rsb:call> The default item here is again _out1 A push here would again push the attributes from _out1 The input item at this level would again be _out1 _out1 is swept clean here for the next iteration </rsb:call>
- The default item _out1 is not only the output from operation1, it also serves as input to operation2 unless the "in" parameter is used to call operation2.
- If you choose to write values to this default item they will be swept clean after an item has been iterated over and the rsb:call works on the next item. In other words you will not be able to read a value set in a previous iteration of a rsb:call in the next iteration. To retain values across iteration copy them to a named item.
- When you read attributes within the scope of the second call, you can not only read the values from _out2 but also read values from _out1. The RSSBus Engine links _out[n], _out[n-1] etc. to allow you to read all the values available so far directly using the default item i.e. by not explicitly referring to items _out1, _out2 etc.. This lookup starts from the default item and goes all the way to the bottom until a value is found.
- As shown in the example above when you push an item only the attributes from the item at the top of the stack (default item) are pushed.
: The name of the RSSBus operation to be called. The examples below show the different kinds of operations that can be natively called by RSSBus. They include operations in connectors, remote RSSBus services, local RSSBus services, and public RSS feeds.
<!-- Call to an operation shipped as a connector (*.dll)--> <!-- HTTP is NOT used and the call is NOT to a script (.rsb)--> <rsb:call op="fileListDir"/> <!-- Call to an operation/ service on a remote machine --> <!-- HTTP IS used and the call IS to a RSSBus service(.rsb)--> <rsb:call op="http://www.rssbus.com/connectors/default.rsb"/> <!-- Call to another service on an existing machine without using HTTP--> <!-- HTTP is NOT used and the call IS to an RSSBus service(.rsb)--> <rsb:call op="listUsers.rsb"/> <!-- Call to an existing RSS feed, these naturally are RSSBus services --> <!-- HTTP IS used and the call IS to a public RSS feed --> <rsb:call op="http://news.google.com/?output=rss"/>
- in: A comma-separated list of items used as input when invoking the operation. Attributes are looked up from left to right in the input items specified. The attribute is looked for in the first item; if not found it is looked for in the second item, and so on.
- out: The item where the output attributes are placed. Within the rsb:call scope, the current output item can be retrieved using the item name specified here. You can also use the _out[n] special items or the _pipe items to refer to the call's results.
Note that attributes set within a call are not available outside the scope of a call. To access an attribute outside the scope of a call, you must explicitly copy an attribute to the item you want to use outside the call. If you don't do so, each iteration of the call will delete the attributes from the previous iteration, and at the end of the call, nothing will be left.
- meta: The name of a meta item where the feed-global attributes will be stored after the operation is executed or the feed is retrieved.
- diff: This parameter specifies a filename used to record items seen from the operation. Each time rsb:call is executed, the items pushed out are recorded in this file. If an item has already been pushed in any of the previous calls, it is skipped. In this way only items that have not been seen yet are returned from the call.
The rss:guid attribute in the item is used to determine which items have already been seen and which have not.
- format: This parameter can specify the name of a custom feed formatter used to format the feed returned by rsb:call inside an rsb:script template. This parameter is normally used in RSBTemplates where the contents of the call are to be converted to text in the output response.
<rsb:call op="someOperation" format="rssbus.Formatters.Csv"/>
- save: The save parameter allows you to store the results of an operation in memory to be used again within the same script. This helps to avoid repeated execution of resource-expensive operations and, at the same time, provides flexibility in writing scripts.
To save results of an operation in memory, specify an attribute name in the "save" parameter. The RSSBus engine then saves the items from the called operation in memory, and saves this memory location in the attribute specified in "save". The following example demonstrates the use of the "save" parameter to retain the contents of a call in memory. In this example, the operation "listCustomer" is called only once, and its results are later used twice.
When the first call is made, the results are not only saved in the attribute "modfeed", but changes needed in subsequent calls are also made. In this example, the "modfeed" attribute has a feed with attributes from listCustomer and a new attribute cust:fullname created within the scope of the rsb:call. The call keyword then saves the results of the feed in the item _feeds under the attribute "modfeed" (the one we specified to save the results to). Subsequently we use this saved feed to make two more calls.
<rsb:call op="listCustomer" save="modfeed"> <rsb:set attr="cust:fullname" value="[cust:firstname] [cust:lastname]"/> </rsb:call> <!-- Use the feed that was saved earlier --> <rsb:call op="[_feeds.modfeed]"> <rsb:set attr="to" value="[cust:email]"/><rsb:call op="sendEmail"/> </rsb:call> <!-- Use the feed that was saved earlier --> <rsb:call op="[_feeds.modfeed]"> <rsb:call op="sqlUpdate"/> </rsb:call>
- page & pagesize: Used to enable paging of the operation or feed results. Together, they determine a subset of items that will be iterated through. For example, if you specify page="2" and pagesize="5", the rsb:call keyword iterates only through items 6 to 10 of the resulting feed.
- auth, username & password: Used to access remote feeds that require authentication. The auth argument can be either "basic" or "digest".
- _index: The output attribute _index shows the index of the item being currently iterated over by rsb:call.
- _op: The name of the operation being called. This is helpful when the operation name is not known until execution.
The following example calls an RSSBus operation using the default item as input:
The following example calls a URL to push the items of a feed:<rsb:call op="fileListDir"> <rsb:push/> </rsb:call>
The following example calls another rsb:script. It shows how you can nest services by writing them in separate scripts and then calling them from a master script:<rsb:call op="http://rss.slashdot.org/Slashdot/slashdot"> <rsb:push/> </rsb:call>
The following example calls another rsb:script that is on a remote machine. Just as in the previous example, a script is being nested; in this case, the script is on a remote machine.<rsb:script xmlns:rsb="http://www.rssbus.com/ns/rsbscript/2/"> <rsb:restrict path="."/> <rsb:info title="File Service" desc="Create a service from a directory listing of files using the fileListDir operation."> <ns prefix="file" name="http://www.rssbus.com/ns?file/2/" /> <input name="path" desc="The path of the directory to list." default="." required=true /> <input name="mask" desc="The mask to use while listing files." default="*" /> <output name="atime" desc="The a time of the file." /> <output name="attributes" desc="Attributes of the file." /> </rsb:info> <rsb:call op="fileListDir"> <rsb:push title="[rss:title]: [file:size] bytes" /> </rsb:call> </rsb:script>
The following example explicitly uses an input item to pass arguments to an operation:<rsb:call op="http://someplace.com/customerList.rsb"> <rsb:push/> </rsb:call>
<rsb:set item="input" attr="feed#1" value="fileListDir"/> <rsb:set item="input" attr="feed#2" value="rsbListOperations" /> <rsb:call op="feedConcat" in="input"> <rsb:push/> </rsb:call>
- rsb:first : To learn how you can write elements to be executed only for the first iteration of the call.
- rsb:catch : To learn how you can catch errors within a call.
- rsb:continue : To learn how you can continue to the next item of the operation.