PLUSNative: Calling SOLO Server XML Web Services

One can easily use the PLUSNative library to call any of the SOLO Server web services that are XML-based and accept string post data. For information on using the XML Activation Service Web Service please refer to the Activating and getting a License File topic in the manual. An overview of the available web services can be found in the SOLO Server manual's Web Services Overview topic.

As an example, this topic will demonstrate calling the XML License Service's UpdateCheckS web method, which can be used by your application to periodically check for new versions.

Building the Request

You must manually build the XML request document to pass to the web service. The XML helper functions provided by the PLUSNative library are recommended for this purpose. The SOLO Server manual documents the XML schema for each web methods request (the input) and response (the output) documents.

The following code snippet demonstrates building the request for the UpdateCheckS web method:

C/C++
//declare variables
char *url = "secure.softwarekey.com/solo/webservices/XmlLicenseService.asmx/UpdateCheckS";
SK_ResultCoderesult = SK_ERROR_NONE;
SK_ApiContextcontext = NULL;
SK_XmlDocrequest = NULL;
SK_XmlDocresponse = NULL;
intresultCode = 0;
intstatusCode = 0;
char *latestVersion = NULL;

//initialize API context (usually called during application start-up)
//refer to the Configuring the API Context topic for instructions


//create a new XML document
result = SK_XmlDocumentCreateFromString(SK_FLAGS_NONE, "<LicenseUpdateCheck></LicenseUpdateCheck>", &request);

//append elements
result = SK_XmlElementAddNew(SK_FLAGS_NONE, request, NULL, "LicenseID", "123" );
result = SK_XmlElementAddNew(SK_FLAGS_NONE, request, NULL, "Password", "");
result = SK_XmlElementAddNew(SK_FLAGS_NONE, request, NULL, "ProductID", "0");
result = SK_XmlElementAddNew(SK_FLAGS_NONE, request, NULL, "ProductName", "My Product");
result = SK_XmlElementAddNew(SK_FLAGS_NONE, request, NULL, "LanguageCode", "en");
result = SK_XmlElementAddNew(SK_FLAGS_NONE, request, NULL, "VerifyDaysToDL", "False");
result = SK_XmlElementAddNew(SK_FLAGS_NONE, request, NULL, "Version", "1.0.0.0");

The above request is built using fictitious, hard-coded data for demonstration purposes. The code snippet above omits many of the parameters necessary to initialize the API context (the context variable). Refer to the Configuring the API Context topic for instructions and a complete example of calling the SK_ApiContextInitialize function.

Calling the Web Service

The code snippet below simply calls the web service using the request we built above. If the request contains a PrivateData node and the API Context has been configured to use the SK_FLAGS_USE_ENCRYPTION and SK_FLAGS_USE_SIGNATURE flags globally, the request will be encrypted and digitally signed with the call to SK_CallXmlWebService.  (This does not apply to this example because it does not contain a PrivateData node in the request.)

C/C++
//call the web service
result = SK_CallXmlWebService(context, SK_FLAGS_NONE, url, request, &response, &resultCode, &statusCode);

//free our request document
SK_XmlDocumentDispose(SK_FLAGS_NONE, &request);

//check the result
if (SK_ERROR_NONE != result)
{
//handle error condition
...
}

Determining the Result

When SK_CallXmlWebService returns 0 (zero), a valid response with no errors was received.

If you receive a result of SK_ERROR_WEBSERVICE_RETURNED_FAILURE, this indicates we successfully received a response, but SOLO Server encountered errors while processing the request. SOLO Server's web service error condition is returned in the resultCode parameter. References are available online for possibleSOLO Server result codes. However, some SOLO Server web services have their own specific result codes that are documented in their respective web service topics in the manual. Many web services also return a human-readable error message that can be extracted from the response document's ErrorMessage node.

Parsing the Response

Once you determine the web service call succeeded, you must manually parse the response to determine what actions to take. Again, the XML helper functions are used here to extract the data out of the response document. The SK_XmlNodeGetValue* functions take an XPath to select the node in the document that you want to get the value of. In this example, the documents root node is LicenseUpdateCheck and we want to get the LatestFreeVersion node's value as a string. Normally, you would need to consider more than just this single node's value in a real-world example.

C/C++
//get the latest free version
result = SK_XmlNodeGetValueString(SK_FLAGS_NONE, response, "/LicenseUpdateCheck/LatestFreeVersion", FALSE, &latestVersion);

//free our response document
SK_XmlDocumentDispose(SK_FLAGS_NONE, &response);

if (NULL != latestVersion)
{
//display update notification to user
...
}

//free our string
SK_StringDispose(SK_FLAGS_NONE, &latestVersion);
Important

These basic source code examples omit important and necessary error checking for the sake of clarity. Many of the functions used could fail for one reason or another, and it is important that you make sure each function call succeeds before passing the result from one function to another. Otherwise, you may not be able to tell exactly where a problem originated if and when one occurs.