Sophis Risque: how to develop a IIS webservice using the API?
7/16/2014 11:28 PM
I've decided to restore some posts that were published on the previous it-quants.com website. These posts are old and published between 2007 and 2008, but are still interesting. One of the most interesting post described how to build a IIS webservice in order to export some functions that can be used by Talend, which is now a well-known French ETL tool.
This is the first post published in November 2007:
This resource was generated in order to show how to develop webservices, or other servers, which use the Sophis C++ API, or even the .Net (SphDotNetToolkit) wrapper proposed by Sophis.
In fact, I was asked recently for developing some ETL treatment, that receives as inputs flat files, shall generate as outputs instruments and deals for Sophis (and for another front-office software too), and using as other inputs some Sophis information (theoretical prices, spots, discount factors...).
I discovered a pretty free ETL tool, Talend, which enables the mixing different inputs like flat files, data issued from webservices or directly from databases, and permits you to generate for instance XML files, in order to integrate them in the Sophis XML gateway. The design of jobs is quite simple by using the drag & drop of built-in components. Other components can be easily developed too, but that is not the purpose of this article:
The above designed job makes the following task: it asks the database for some instruments, it lists the currencies present in the database, it adds the spot of the funding rate of the corresponding instrument currency through a webservice and finally generates a XML file as output.
Building a webservice using the .Net technology (C# or managed C++) is quite easy, since Visual Studio proposes to the developer all assistants that help him to generate the appropriate code. The most difficult in building servers that make queries on the Sophis API is that the API is not thread-safe, for many reasons:
- first, it uses visible global variables: for instance, the global market data (gApplicationContext in C++), and all derivated objects (instruments stored in the cache).
-second, other unvisible variables like private objects that enable queries on the Oracle database are not thread-safe too: the Oracle OCI makes some thread specific memory allocation for instance, using the Win32 SDK TlsAlloc.
So, for these reasons, when building the server, before calling the Sophis API, you have to serialize your differents calls that occur on different threads to a single thread. When you ask to the Sophis developers, the CSRApi::Initialise have to be done on the main thread of the application and all other calls to the API on this thread too, but in fact, if you are not using such other treatments that occur on other threads like the CORBA ones and DRT connections, you don't need really to make the Initialisation on the main thread, but only to make calls to the API on the same thread.
In this resource, you will see then that the API is initialized on a specific thread, that is not the main thread (sure, the main thread in a web service is quite difficult to capture since calls to your webservice code are made on different threads whose allocation is not really controlled by the developer, isn't it).
When another call is made hereafter, it could be done of course on the same thread, but since IIS is controlling the thread allocation, the best is to make the balancing on the Sophis API initialisation thread yourself. The only way to make that is to control the thread initialisation at the beginning on which you make the Sophis API initialisation.
After, it is quite simple, we just have to control the synchonization between our API thread and the web client threads on which the web service calls are occuring. Such a thing can be done by encaplusating all the calls in some C++ macro like that (nota: I didn't really understand why the __cdecl tag is needed to debug the code on VS 2005, even all the project is already __cdecl enable):
_result = 0.0;
(currency && _result)
_ident = CSRCurrency::StringToCurrency(currency);
CSRCurrency* _currency = CSRCurrency::GetCSRCurrency(_ident);
*_result = m_marketData->GetSpot(_currency->GetFundingRate());
Nota: for configuring the web service, the web.config file should be edited and the "Sophis folder" variable initialized.
Code provided: ITQWebService.zip