- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
One of my post my past blog posts talked about SOAP Web Service and time zones examples. I will discuss now a race condition that can cause missing service catalog items or attached to the wrong request REQ.
Let's talk about
- Service Cart API
- Scripted Web services
- Example of scripted webservices where request items got missing or in the wrong request
Service Cart API
The Service Catalog application is a way for customers to order pre-defined, bundled goods and services from your IT organization or other departments. It offers a consistent and intuitive online ordering experience with as much flexibility as you need. The catalog is a structured commodity with its own description, fields, price, and execution schedule.
A scriptable cart API for the service catalog makes it easier to order from the catalog when using business rules.
The cart API allows you to order any quantity of catalog items, using the sys_id of the Catalog Item [sc_cat_item] you want.
You can then set catalog variables to values as required, assuming the variables have names.
Scripted Web services
Scripted Web Services allow a ServiceNow administrator to create new web services that are not addressed by the system. You can define input and output parameters for the web service and use JavaScript to perform operations. Though this feature is very powerful, use Direct Web Services or Web Service import sets instead whenever possible since they are simpler to implement and maintain.
Example of scripted webservices where request items got missing or in the wrong request
This is an example to create requested Items (RITM) from Service Catalog API that causes some items to disappear or get attached to the wrong REQ request.
In this example I will show you how cart() API could cause Requested Items disappearing or attached to the wrong request.
I will explore one possible cause that is sometimes overlooked:
--> RACE CONDITIONS on the new Cart() call.
Race conditions are difficult to avoid and they are present on most applications.
i.e. Threads "racing" to access/change the data.
On this example, I will explore why some Requested Items (sc_req_item) disappear or get assigned to the wrong cart just by an incorrect script using our Cart API.
A scriptable API for the service catalog makes it easier to order from the catalog when using business rules (e.g. Email Inbound Actions, Scripted Web-services, etc)
In more detail, you can use our Service Catalog API Cart by giving an explicit-cartID e.g. new cart("cartID"). Or you could leave the system to assume a new cart by the call Cart(). However, this is attached to the user you are executing with (shared resource).
Both calls will generate a cart. However, only on the first call you have control to guarantee an UNIQUE-ID.
This is important because if you are generating multiple cart request that may run in parallel, the multiple cart() calls generated on each transaction can have race conditions. To avoid that, you just need to explicitly give a unique id.
Below is a an example of a simple Scripted Web service to explain this:
For these testings, we will submit two items each of the 'cat_item' per request. The items will be request 1: 2x Acrobat (sys_id 7198552237b1300054b6a3549dbe5dea) request 2: 2x Apple iPad 3 (sys_id 060f3afa3731300054b6a3549dbe5d3e) The script is:
With the generatedID, you do not have problems. Executing the Scripted script. Checking in sc_req_item.list , we can see the two items attached to each request. However, with > var cart = new Cart(); if you execute two simultaneous calls, it appears same instance* of cart is used to add items and place only one order. You will also notice that adding a slight delay for one requested item would place more or less items into same order. On my testings: Checking in sc_req_item.list there is only two records. REQ0010031 is missing. That is caused by an incorrect usage of Cart API. The way the Cart API is being used, does indeed use the same instance of a cart. Note: If the script runs as a result of a scheduled import, the script runs as system or as the user specified by that import in the Run as field. The script uses the specified user's cart. Each call to new Cart() empties the cart of the calling user, but does not use or empty any other carts. |
In conclusion, if you are writing complex scripts with chance of concurrency (email, soap, etc), give an unique-id to you new cart created if you are having missing request items (or attach to the wrong request). Note* that different users, run on different cart(). This is only one possible explanation.
More information can be found here:
- Import and Export Resources Page (KB0541631)
- Docs: Web services
- Docs: Scripted REST APIs
- Docs: SOAP web service
- Docs: Service Catalog
- Docs: Service Catalog API
- My other blogs
Thank youBen Phillips
Q. Is there other example to create a unique id?
Answer. Yes, see the example below:
// note this is an example.
var cartId = GlideGuid.generate(null);
var cart = new Cart(cartId); // <--- with Unique id
- 11,331 Views
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.