Best Practices for Publishing and Consuming Web Services with ServiceCenter

armyfertileΑσφάλεια

3 Νοε 2013 (πριν από 3 χρόνια και 7 μήνες)

88 εμφανίσεις


Best Practices for Publishing and Consuming Web Services
with ServiceCenter
®

Introduction.........................................................................................................................................2

Overview........................................................................................................................................2

Definitions, Acronyms and Abbreviations........................................................................................2

Purpose..........................................................................................................................................2

The ServiceCenter Web Services features...............................................................................................3

Introduction to Web Services in ServiceCenter.....................................................................................3

Consuming an external Web Service from ServiceCenter......................................................................4

Example: Calling a Web Service sample from the ScriptLibrary........................................................5

Example: Getting up-to-date currency data from a Web Service.........................................................5

Publishing ServiceCenter data...........................................................................................................9

Understanding the ServiceCenter Web Service..............................................................................10

Things to consider prior to publishing data....................................................................................14

Example: Publishing data from the currency and curconvert files.....................................................16

Consuming a ServiceCenter Web Service.........................................................................................24

Retrieving data from ServiceCenter...............................................................................................25

Example: Retrieving ServiceCenter price lists into a text file using Connect-It.....................................26

Example: Getting currency information and pricelist information from another ServiceCenter system....29

Using the ServiceCenter Web Services examples in the RUN directory.................................................31

Troubleshooting.................................................................................................................................32

What to do if the WSDL2JS utility fails..............................................................................................32

What happens if an exposed table is tailored?..................................................................................33

Debugging....................................................................................................................................33

debughttp..................................................................................................................................33

RTM:3 and debugdbquery:999...................................................................................................34

Testing your WSDL using .NET Web Service Studio...........................................................................34

Advanced Troubleshooting..............................................................................................................36

How to troubleshoot a Web Service that is behind a closed firewall.................................................36

Special considerations for using Keep-Alive with ServiceCenter servlet mode........................................40

Is it possible to consume Web Services in ServiceCenter through a proxy server?..................................41

Error Messages..............................................................................................................................41

Appendix.........................................................................................................................................46

Understanding the return codes provided by the ServiceCenter Web Service........................................46

Using SSL connections to connect to an external Web Service.............................................................49

Steps to take when modifying an existing extaccess record.............................................................50

Syntax for Entity References in XML..................................................................................................50

What does a nillable field designate and what is its purpose?.........................................................51

Best Practices.................................................................................................................................51

Writing a JavaScript for consuming a Web Service........................................................................51

Date/Time handling in the self-written JavaScript............................................................................51

Writing expressions in extaccess..............................................................................................52

References........................................................................................................................................52

For more information..........................................................................................................................53


Introduction
Overview
Information that is available on standalone systems would be much more useful to a company if it
were shared with other applications. In the past, sharing valuable information required complicated,
customized, and expensive integrations between the applications.
With the introduction of Web Services, application integration is made easier because it allows
applications to use any Web Service independently of the platform or programming language in
which it was developed. In addition, integrations based on Web Services are less expensive to
maintain and very flexible, which makes them an ideal solution for integrations between different
systems.
With a Web Service, data is exchanged using XML and the Simple Object Access Protocol (SOAP).
Web Services are applications that are generally available via the World Wide Web. They are
specified with a URL that programmatically returns requested information to a client. Web Services
can integrate with other applications or Web sites, either on the same server or on servers located all
over the world.
For example, a travel Web Site could process a user’s request for weather and flight information at
any destination by making behind the scenes calls to Web Services that provide this information.
Then the travel site displays the results to the user. This eliminates the need for the user to go to
various sites to get this information.

Figure 1: Typical example of Web Services
Definitions, Acronyms and Abbreviations
Term
Definition
Consuming
Using a Web Service by calling its methods, supplying the appropriate calling parameters
Publishing
Providing a Web Service by answering a call and returning the expected results
WSDL
Web Services Description Language, which is a standard, structured way of describing
SOAP messages and Web Services

Purpose
This document provides guidance for users who wish to publish or consume Web Services using
ServiceCenter. It includes examples that can be used as templates.
2

Web Services and their clients can be written in any programming language and for any platform.
ServiceCenter Web Services ships with examples using both the Java

and Visual C#
®
programming
languages.
In addition, the examples are all based on ServiceCenter 6.1. Although the ServiceCenter 6.0 Web
Services APIs are still available, changes and improvements to the Web Services features in
ServiceCenter 6.1 makes it the recommended release to use.
The ServiceCenter Web Services features
The ServiceCenter Web Services features provide the ability to communicate and integrate with
applications in an open and efficient manner. These services are useful in many ways. They provide
the ability to use a third-party application inside ServiceCenter, manipulate ServiceCenter data inside
your custom application, or transfer data among separate ServiceCenter systems. With this flexibility
comes the responsibility for developers and administrators to design and implement their integrations
well, and to remain well versed in the concepts and practices of well built Web Services.
Introduction to Web Services in ServiceCenter
ServiceCenter 6.0 provides both a standard common integration to other industry applications and
the ability to publish ServiceCenter information as Web Services. This initial implementation was
table-oriented rather than service-oriented, meaning that data was exposed one table at a time using
the table name in ServiceCenter. Although the 6.0 Web Services API achieved its essential objective
of exposing ServiceCenter application functionality via Web Services, it was hard to use because:
• It required knowledge of the historic low-level ServiceCenter schema. For example you had
to know that the probsummary table is where ServiceCenter stores incident records.
• It did not use XML schema data types such as dateTime. This meant that dates were served to
Web Services client programs as strings, formatted according to operator-specific preferences
rather than in a standard, predictable, time zone-independent format.
• ServiceCenter 6.0 also required users to consume Web Services on a special, dedicated
“apiserver” TCP/IP port that was separate from the actual ServiceCenter server port; and this
port could handle only a single SOAP request at a time.
In ServiceCenter 6.1, the Web Services features were greatly improved to be able to both publish
and consume Web Services and to allow publishing Web Services using the default ServiceCenter
listener port. This change made communications less complicated and improved performance. Also,
an abstraction layer was introduced which allowed ServiceCenter to expose its Web Services using
much more user-friendly names. (For example, to create an Incident, one would issue a
CreateIncidentRequest rather than a “probsummaryAdd” request.) In addition, several ITIL-based
services were published as part of the out-of-the-box ServiceCenter 6.1 system. These WSDLs expose
several data elements from different tables in order to provide basic ITIL workflows via the Web
Services API. The following ITIL
®
based WSDLs are provided out of the box:
• IncidentManagement
• ConfigurationManagement
• ServiceManagement
• ProblemManagement
Note: Table-based WSDLs are still available in ServiceCenter 6.1 for users who have previous Web
Service applications for ServiceCenter 6.0.
To publish a ServiceCenter Web Service, you create one extaccess record per table that you want to
publish in that Service, and modify the data policy record for this table. The extaccess and data
policy records for a table are displayed as a joined file when displayed from the Web Services
3

Utilities. Though configuration changes can be made directly to data policy, HP recommends that you
make them using the WSDL Configuration Utility. To use the utility, click Toolkit -> WSDL
Configuration Utility.
Important: Changes to the WSDL Configuration Utility affect any client that is currently consuming
them. If you modify this configuration, make sure to test all other applications that consume the Web
Service and address possible issues immediately.
The ServiceCenter server requires that each Web Service request provide a valid operator name and
password combination. These must be supplied via a standard HTTP Basic Authorization header.
SOAP toolkits universally support this authentication mechanism. Use SSL if you are concerned about
the possibility of someone using a network monitoring tool to discover passwords. Basic
Authorization by itself does not encrypt the password; it simply encodes it using Base 64. In addition
to having a valid login, the operator must have the SOAP API capability word to access the Web
Services API. If the Web Service request does not contain valid authorization information, then the
server sends a response message containing “ResponseCode: 401 (Unauthorized).” If the request is
valid, then the server sends a response message containing the results of your Web Services
operation. The response message contains only the information that the operator is allowed to see.
Both Document Engine and Mandanten security group settings are maintained through the Web
Services API.
Consuming an external Web Service from ServiceCenter
You can configure ServiceCenter to connect to and exchange information with remote Web Services.
ServiceCenter uses a built-in Web server to send and receive SOAP messages to Web Services, but
internally the server uses JavaScript

to create and format the proper SOAP messages.
Note: For a production application that needs services that are not available within your corporate
intranet (such as postal address verification, email address verification, and currency conversions) HP
recommends that you investigate offerings from established for-fee Web Services vendors. Although
there are a lot of free and demo Web Services, we do not recommend basing a production
application on such services, since availability of the service is not guaranteed. Several Web sites
such as
www.xmethods.net
publish lists of available free and fee-based Web Services. (Be sure to click
the full list button to see the complete list of Web Services.)
To consume a Web Service from ServiceCenter perform the following steps.
1.
Obtain the URL to the Web Service's WSDL file.
2.
Examine the WSDL either as a text file, or using a third-party graphical WSDL analysis tool to
determine what functions, inputs, and formats the Web Service expects. Some third-party Web
Services tools allow you to experiment interactively with Web Services. HP recommends that you
familiarize yourself with the Web Service using such a tool before beginning any ServiceCenter
JavaScript work.
3.
Execute the Run WSDL to JS wizard to obtain and convert the Web Service's WSDL into
JavaScript.
4.
Write custom JavaScript to call the JavaScript functions generated by the WSDL to JS wizard.
These functions will enable you to create and send the SOAP messages required to interact with the
Web Service. HP recommends that you write a short “standalone” script and invoke it from the
Script Library utility to test it prior to implementing the JavaScript call from format control, triggers,
or display options. After you have determined and debugged the JavaScript code required to
invoke the service, you can then integrate the script with your ServiceCenter application.
5.
Tailor your ServiceCenter application to invoke your custom JavaScript when you want to connect
to a remote Web Service. Usually Web Services are invoked from the Document Engine, Format
Control, Links, Display application, or from similar tailoring tools. For testing purposes, the
JavaScript code can be called from within the ScriptLibrary record itself before being called from
any of the other tailoring tools.
4

Example: Calling a Web Service sample from the ScriptLibrary
The ServiceCenter ScriptLibrary contains a JavaScript sample that invokes a delayed stock quote Web
Service. To test it, go to the Database Manager in ServiceCenter and select the ScriptLibrary
format. Select the record named DelayedStockQuoteTest and you will see the following Java
Script:
var stockQuoteService = new lib.DelayedStockQuote.DelayedStockQuote();
// Create the Service Object for the delayed stock quote Web Service

var getQuote = new lib.DelayedStockQuote.GetQuote();
// Create the Request Object for the GetQuote request

var symbol = "GOOG";
// define the stock symbol to search for

getQuote.StockSymbol.setValue( symbol );
getQuote.LicenseKey.setValue("0");
// define the stock symbol and license key for the request

var getQuoteResponse = stockQuoteService.invoke(getQuote);
// invoke the web service using the Service Object and passing the
// Request Object

var quoteResult = getQuoteResponse.GetQuoteResult;
// retrieve the response of the previous request

var tradeDateTime = quoteResult.LastTradeDateTime.getValue();
// get the value of the last trade date and time

var xmlDt = new XMLDate( tradeDateTime );
// and convert it to an XML formatted date.

print( "Most recent trade of " + quoteResult.CompanyName.getValue() + "
was at " + quoteResult.LastTradeAmount.getValue() + " at " +
xmlDt.JSDate() );
Note: This example script does not abide to coding best practices. Refer to the Best Practices section
in the Appendix for more information.
Enter any stock symbol in the “var symbol =” line, such as:
var symbol = "HPQ"
This would retrieve the latest stock quote for Hewlett Packard. Save the record and click Execute to
invoke the Web Service. The result will be the following message:
Most recent trade of HEWLETT PACKARD C was at 32.88 at Tue May 23 2006
03:25:00 GMT-0700 (Pacific Daylight Time)
Example: Getting up-to-date currency data from a Web Service
The ServiceCenter Request Management module is used to order products and services from
international vendors for users around the world. Sometimes, it may be more cost efficient to order
from another country than to order locally. The examples in this document show how to get current
currency information and calculate an objects’ price in different currencies. If you were to
incorporate these Web Services into a production system, make sure to always use license-based
Web Services that guarantee their availability.
1.
Find a provider that publishes a currency exchange rate WSDL

Note: With any free provider, it is possible that the Web Service is available only for a short
period. This example shows how to integrate any Web Service into ServiceCenter. For an
example of a for-fee currency conversion tool that can be used instead of the following example,
5

refer to the XigniteCurrencies record in the ScriptLibrary file.

2.
In ServiceCenter, go to Menu Navigator and click Utilities –> Tools –> Web Services. Click
Run WSDL to JS.
3.
Enter the URL to the WSDL, such as :

http://www.<anywebserviceproviderhere>.com/CurrencyConvertor.wsdl

4.
Click Proceed.
5.
Click Add to add the new ScriptLibrary record called CurrencyConvertor.
6.
Write an interfacing JavaScript record in the ScriptLibrary called CurrencyConvertorRUN, as
follows:

function GetCurrencies(From, To)

var Currencies = new
system.library.CurrencyConvertor.CurrencyConvertor();
// first, initialize the Service Object for this JavaScript

var Curr=Currencies;
// put the result of that call into a differently named variable
// (not always necessary)

var validCurrencies=new Array("AED","AFA","ALL","ANG","ARS","AUD",
"AWG","BBD","BDT","BHD","BIF","BMD","BND","BOB","BRL","BSD","BTN","BWP","
BZD","CAD","CHF","CLP","CNY","COP","CRC","CUP","CVE","CYP","CZK","DJF","D
KK","DOP","DZD","EEK","EGP","ETB","EUR","FKP","GBP","GHC","GIP","GMD","GN
F","GTQ","GYD","HKD","HNL","HRK","HTG","HUF","IDR","ILS","INR","IQD","ISK
","JMD","JOD","JPY","KES","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK"
,"LBP","LKR","LRD","LSL","LTL","LVL","LYD","MAD","MDL","MGF","MKD","MMK",
"MNT","MOP","MRO","MTL","MUR","MVR","MWK","MXN","MYR","MZM","NAD","NGN","
NIO","NOK","NPR","NZD","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","Q
AR","ROL","RUB","SAR","SBD","SCR","SDD","SEK","SGD","SHP","SIT","SKK","SL
L","SOS","SRG","STD","SVC","SYP","SZL","THB","TND","TOP","TRL","TTD","TWD
","TZS","UAH","UGX","USD","UYU","VEB","VND","VUV","WST","XAF","XAG","XAU"
,"XCD","XOF","XPD","XPF","XPT","YER","YUM","ZAR","ZMK","ZWD")

var currenciesTemp=validCurrencies.toString();

if (currenciesTemp.indexOf(From)>0)
{
var myRate = new system.library.CurrencyConvertor.ConversionRate();
// Create the Request Object
myRate.FromCurrency.setValue(From);
myRate.ToCurrency.setValue(To);
// Fill the required input values that specify the query / request into
// the Request Object(see below on how to find them)

var ConversionRateResponse = Curr.invoke(myRate);
invoke / call the web service and pass in the Request Object
var result = ConversionRateResponse.ConversionRateResult;

Request the result instance of the previous call

var conversionRate=result.getValue();
get the value that was returned in the result instance for further use
}
else
{
print( From + " is not a valid Currency for this rate converter.
Proceeding to next currency.")
return 0;
}
}
6

Retrieving relevant data from the generated JavaScript to create the calling
JavaScript
Check these sections in the “master” JavaScript to write your calling JavaScript:
The first line in the master code gives the name of the main function or Service Object to call first in
the calling JavaScript:
function CurrencyConvertor()
1.
Find the function that does what is needed; in this case, performs a currency conversion:

function ConversionRate()
{
this.$$attributes = new Array();
this.$$xmlNames = new Array();
this.$$objNames = new Array();
this.getName = getName;
this.getXmlName = getXmlName;
this.setContent = setContent;
this.addContent = addContent;
this.getContent = getContent;
this.isFault = isFault;
this.$$elementChildren = new Array();
this.$$name = "ConversionRate";
this.$$xmlNames[ "ConversionRate" ] = "ConversionRate";
this.xmlns = new String("http://www.webserviceX.NET/");
this.$$attributes.push( "xmlns" );
this.FromCurrency = new Currency();
this.$$elementChildren.push( "FromCurrency" );
this.ToCurrency = new Currency();
this.$$elementChildren.push( "ToCurrency" );
}

The bold $$elementChildren.push sections give the parameters that have to be filled in the calling
JavaScript using setValue or a similarly defined function.
function setValue( value )
{
this.$$value = value;
}

2.
Check which parameters the invoke() function expects:

function invoke( requestObj, headerObj )
In this case, the headerObj was optional (was “nullsub’ed” in the JavaScript code), so the requestObj
is the only required argument.
3.
Check the syntax for the Response function:

function ConversionRateResponse( )
{
this.$$attributes = new Array();
this.$$xmlNames = new Array();
this.$$objNames = new Array();
this.getName = getName;
this.getXmlName = getXmlName;
this.setContent = setContent;
this.addContent = addContent;
this.getContent = getContent;
this.isFault = isFault;
this.$$elementChildren = new Array();
this.$$name = "ConversionRateResponse";
7

this.$$xmlNames[ "ConversionRateResponse" ] =
"ConversionRateResponse";
this.ConversionRateResult = new s_double();
this.$$elementChildren.push( "ConversionRateResult" );
}

4.
Call this function with the method defined in the $$elementChildren.push section (shown above in
bold).
5.
Use getValue (or a similarly defined function) to read the result of the request.

function getValue( )
{
return this.$$value;
}

6.
Use the calling JavaScript to update values in ServiceCenter. Rewrite the calling JavaScript to be
a callable function such as:

function GetCurrencyFromSC()
{
var CurrCode="";
var CurrencyRecord=new SCFile("currency");
var CurrConvRecord=new SCFile("curconvert")
var foundCurrency = CurrencyRecord.doSelect( "true" );
while ( foundCurrency == RC_SUCCESS )
{
USDConversionRate =
system.library.CurrencyConvertorRUN.GetCurrencies(CurrencyRecord.cu
rrency_code, "USD")
if (USDConversionRate > 0)
{
CurrConvRecord.currency_code=CurrencyRecord.currency_code;
CurrConvRecord.rate=parseFloat(USDConversionRate);
CurrConvRecord.root_code="USD";
CurrConvRecord.date=system.functions.tod();
var rc = CurrConvRecord.doInsert();
if (rc != RC_SUCCESS)
{
print( "Could not insert currency conversion record. " +
RCtoString( rc ) );
}
}
else
{
print(" Invalid Conversion Rate returned." + USDConversionRate)
}
foundCurrency = CurrencyRecord.getNext();
}
}

7.
Call the JavaScript from the schedule file to regularly update the currency values. Add a
schedule record as shown below to weekly update the curconvert file:

Note: Invoking a Web Service can be very resource and time intensive. Carefully consider batch
processing as shown below, and do not use it to invoke a Web Service multiple times during the
day, since this would negatively influence system performance. Batch processing should only be
done off-hours if overall calls to the Web Service can be minimized this way.

8


With this example, we are now able to receive real-time currency conversion rates into ServiceCenter
that can be used in the procurement and service chargeback processes.
Publishing ServiceCenter data
Publishing ServiceCenter data can be used to expose files and methods to add or update records
within ServiceCenter from any application. This application could be a custom made C# or Java
program. An interface program such as Connect-It or another ServiceCenter system could consume
the published ServiceCenter data as well.
To expose a set of ServiceCenter tables as a Web Service, click Utilities -> Tools -> Web
Services -> External Access and create or update the related extaccess records and data policy
records. As an example, the Change Management Service contains two tables: cm3r and cm3t.
When the ChangeManagement Web Service is exposed, the wsdl will contain field names and
actions for both ServiceCenter files. In the extaccess record, note the Object Names of Change and
Changetask. These Object Names are going to be exposed via the WSDL rather than the sometimes
cryptic table names.
The following picture shows how the extaccess and datadict portions of the WSDL configuration utility
work together with Document Engine and the dbdict.

9


Understanding the ServiceCenter Web Service
To understand the meaning or use of a particular field or element within a document defined in the
WSDL you must understand the ServiceCenter data model and business logic for the application
which defines the data. The WSDL and logic of ServiceCenter Web Services is dynamic, so if a
customer adds fields to a file which is exposed as a Web Service, and adds business logic that
requires those fields, then these new fields and business logic will be immediately reflected in the
WSDL. The vast majority of objects described in the WSDL and the XML schema are ServiceCenter
fields whose meaning is defined by a particular ServiceCenter application. Before approaching any
Web Services consumption project, it is important to understand the data model that is implemented
within the ServiceCenter instance you are targeting. Every ServiceCenter implementation will have a
slightly different data model and business logic. Therefore, the set of fields which must be supplied in
a request such as CreateIncidentRequest will depend on the particular installation or implementation.
Every Web Service published by ServiceCenter is a document-literal service. The documents which
are used for the requests and replies are derived from the dbdict definition of a single ServiceCenter
file, since most ServiceCenter applications store large, complete objects in a single file. For example,
ServiceCenter stores Change objects in a file called cm3r, and therefore the cm3r file is consulted to
prepare the ChangeManagement WSDL. Likewise, ServiceCenter stores Incident objects in a file
called probsummary.
Web Service definitions are maintained in the WSDL Configuration Utility. In this utility you can see
how file names such as probsummary are aliased to Incident, how fields within files are either
exposed or excluded for purposes of Web services; and how they are aliased to more appropriate
names. Since the historic ServiceCenter file names for various objects do not match current ITIL
standards, these names are aliased to more appropriate names when exposed via a Web Service.
(For example, the probsummary file becomes Incident and the number field in probsummary
becomes IncidentID.) Finally, the WSDL Configuration Utility is where XML schema data types such
as dateTime can be applied to individual fields. The default type is string, but ServiceCenter fields
can be mapped to various XML schema types if needed.
10

Example: Retrieving data from ServiceCenter via a Web Service
The simplest way to perform retrieval operations is via Query-by-example (QBE). This is done by
creating an instance of a particular kind of object (such as an Incident) and populating one or more
fields with values to determine the result set.
This instance is then used in a RetrieveXXXKeysList operation. In a program, such as the sample
programs provided with ServiceCenter, you would be assigning values to properties or calling setter
methods on various Java or C# or other objects. In the following example, we submit a
RetrieveIncidentKeysList object, supplying only a value for "Category". We get back a
RetrieveIncidentKeysListResponse object listing the primary keys of the matching Incident objects.
Note that we only have to supply values for the fields on which we wish to select.
The request:
<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-
ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<RetrieveIncidentKeysListRequest filename="probsummary"
xmlns="http://servicecenter.peregrine.com/PWS/2005-05-02/">
<model>
<keys>
<IncidentID/>
</keys>
<instance>
<Category>telecoms</Category>
</instance>
</model>
</RetrieveIncidentKeysListRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

ResponseCode: 200 (OK)
Pragma:thinktime="0"
Connection:Close
Content-Length:1102
Cache-Control:no-cache
Content-Type:text/xml; charset=utf-8
Set-Cookie:SessionId=127.0.0.1:4139;Version=1
Server:gSOAP/2.2
The response:
<?xml version="1.0" encoding="utf-16"?>
<SOAP-ENV:Envelope xmlns:SOAP-
ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-
ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://servicecenter.peregrine.com/PWS">
<SOAP-ENV:Body>
<RetrieveIncidentKeysListResponse message="Success"
query="category#&quot;telecoms&quot;" returnCode="0"
schemaRevisionDate="2006-09-15" schemaRevisionLevel="14" status="SUCCESS"
xmlns="http://servicecenter.peregrine.com/PWS"
xmlns:cmn="http://servicecenter.peregrine.com/PWS/Common"
xsi:schemaLocation="http://servicecenter.peregrine.com/PWS
http://server:12670/PWS/Incident.xsd
">
<keys>
<IncidentID type="String">IM1049</IncidentID>
</keys>
<keys>
<IncidentID type="String">IM1001</IncidentID>
</keys>
<keys>
11

<IncidentID type="String">IM1059</IncidentID>
</keys>
<keys>
<IncidentID type="String">IM10002</IncidentID>
</keys>
<keys>
<IncidentID type="String">IM1070</IncidentID>
</keys>
</RetrieveIncidentKeysListResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Having retrieved a list of <keys> elements we can now retrieve these Incidents using a
RetrieveIncidentList request, by supplying the collection of keys elements in that request.
You can submit a variable number of <keys> elements in a RetrieveXXXList request, subject only to
your program’s ability to handle large XML responses. Java client programs can sometimes run out of
memory if the server returns very large responses.
If we resubmit the request and supply an <OpenedBy> element with the value of "falcon" in addition
to the Category value of "telecoms", the list of returned keys now contains only 1 IncidentId because
the two query terms are connected with AND. Using this query mechanism there is no way to use OR
to connect query terms. To do that, you must supply an “expert” query as a string.
The request:
<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-
ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<RetrieveIncidentKeysListRequest filename="probsummary"
xmlns="http://servicecenter.peregrine.com/PWS/2005-05-02/">
<model>
<keys>
</keys>
<instance>
<Category>telecoms</Category>
<OpenedBy>falcon</OpenedBy>
</instance>
</model>
</RetrieveIncidentKeysListRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

ResponseCode: 200 (OK)
Pragma:thinktime="0"
Connection:Close
Content-Length:903
Cache-Control:no-cache
Content-Type:text/xml; charset=utf-8
Set-Cookie:SessionId=127.0.0.1:4162;Version=1
Server:gSOAP/2.2
The response:
<?xml version="1.0" encoding="utf-16"?>
<SOAP-ENV:Envelope xmlns:SOAP-
ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-
ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://servicecenter.peregrine.com/PWS">
<SOAP-ENV:Body>
<RetrieveIncidentKeysListResponse message="Success"
query="category#&quot;telecoms&quot; and opened.by#&quot;falcon&quot;"
returnCode="0" schemaRevisionDate="2006-09-15" schemaRevisionLevel="14"
12

status="SUCCESS" xmlns="http://servicecenter.peregrine.com/PWS"
xmlns:cmn="http://servicecenter.peregrine.com/PWS/Common"
xsi:schemaLocation="http://servicecenter.peregrine.com/PWS
http://server:12670/PWS/Incident.xsd
">
<keys>
<IncidentID type="String">IM10002</IncidentID>
</keys>
</RetrieveIncidentKeysListResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The ServiceCenter GUI clients support queries using a special QBE query syntax which involves
special characters such as # ("starts with"), or relational operators such as > or < preceding an
actual data value in the form. This kind of syntax is also supported via Web Services, although if the
field is of a type other than string (for example an integer or dateTime type) and you are using a
strongly typed programming language such as Java or C# to write your client code, you will not be
able to leverage this feature. You cannot do so because the automatically generated proxy code will
not let you set a field on type integer to a string value containing a non-numeric character. In the
following example, we place “#f” in the OpenedBy element, which would work in Java because
OpenedBy is a string. This should retrieve all Incidents opened by operators whose IDs start with the
letter “f.”
The request:
<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-
ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<RetrieveIncidentKeysListRequest
xmlns="http://servicecenter.peregrine.com/PWS/2005-05-02/">
<model>
<keys>
</keys>
<instance>
<OpenedBy>#f</OpenedBy>
</instance>
</model>
</RetrieveIncidentKeysListRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

ResponseCode: 200 (OK)
Pragma:thinktime="0"
Connection:Close
Content-Length:864
Cache-Control:no-cache
Content-Type:text/xml; charset=utf-8
Set-Cookie:SessionId=127.0.0.1:4208;Version=1
Server:gSOAP/2.2
The response:
<?xml version="1.0" encoding="utf-16"?>
<SOAP-ENV:Envelope xmlns:SOAP-
ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-
ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://servicecenter.peregrine.com/PWS">
<SOAP-ENV:Body>
<RetrieveIncidentKeysListResponse message="Success"
query="opened.by#&quot;f&quot;" returnCode="0" schemaRevisionDate="2006-
09-15" schemaRevisionLevel="14" status="SUCCESS"
xmlns="http://servicecenter.peregrine.com/PWS"
xmlns:cmn="http://servicecenter.peregrine.com/PWS/Common"
13

xsi:schemaLocation="http://servicecenter.peregrine.com/PWS
http://server:12670/PWS/Incident.xsd
">
<keys>
<IncidentID type="String">IM10002</IncidentID>
</keys>
</RetrieveIncidentKeysListResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Note: In the response above, the server has populated a "query" attribute on the
RetrieveIncidentKeysListResponse element with the actual query string that was generated from the
input. The field names in such server-generated query strings reflect the actual field names (such as
opened.by instead of OpenedBy). Clients who want to submit an expert/advanced query should use
either the query attribute on the <keys> element or the query attribute on the <instance> element.
Both are provided because some requests do not define any <instance> element. During SOAP API
request processing, the server will look first at the <keys> element and, if there is no query attribute
there, will look at the <instance> element if it exists. Query attributes defined on any other element
are never consulted during inbound SOAP request processing.
The XML document which describes a particular record (such as a Change or Incident) is "wrapped"
in an outer document called a "model", which is nothing more than a container for separating the
actual data (the “instance” part) from the "keys" part, which is metadata about the fields which make
up the primary key of the object.
Things to consider prior to publishing data
Before publishing ServiceCenter data via a Web Service, there are several things to consider. When
investigated thoroughly, each of the following items will serve to improve the organization and
performance of the Web Services.
Can I use the out of the box WSDLs?
The ITIL-standard WSDLs that are provided with ServiceCenter should be used whenever possible.
They have been tested extensively and are well documented, which makes them easier to use. If you
are interested in using one of these WSDLs but wish to make some changes to them, you should make
a copy of the original WSDL by copying the corresponding datadict and extaccess record(s) to
maintain their integrity in case you need to go back to them.
What items do I need to expose?
Though an entire table and even an entire database can be exposed via Web Services, doing so
would cause bad performance and confuse users. Only the data that is needed by a client should be
exposed. This prevents excess traffic and decreases the amount of storage that your client may need
to use.
What data types should I use?
ServiceCenter has a more lenient data typing policy than the XML schema data typing policy used for
Web Services. Certain field types in ServiceCenter can correspond to multiple data types in the XML
schema data type policy. For example, the ServiceCenter decimal data type could be a decimal, a
floating number, or an integer in the XML schema data type policy.
In addition, the actual formatting of data varies between ServiceCenter and XML schema data types.
This is especially true of ServiceCenter date/time fields that use a different order than XML schema
dates. Because some Web Services may require changes to field data format, you can now define
the XML Schema data type to which you want ServiceCenter to convert the field's data when you
publish the field as part of a Web Service.
For outbound data, the ServiceCenter server automatically converts the ServiceCenter data to the
format you select in the data policy record for the ServiceCenter field. For inbound data, the
14

ServiceCenter server automatically converts the XML schema data to the ServiceCenter field's listed
data type format.
The services, objects, and fields published in the ServiceCenter out-of-box Web Services API already
have the proper XML schema data mappings listed in the data policy record. If the data policy does
not list a data type mapping, then the Web Services API treats the field data as a string. Typically,
you need to add or change a Web Services API data type mapping only to publish custom fields that
you have added to ServiceCenter as Web Services objects.
The following table lists the available SOAP API data types and their ServiceCenter equivalents:
SOAP API Data Type
ServiceCenter Data Type
Base64Type
used for binary data
BooleanType
Boolean
ByteType
Decimal
DateTimeType
Date/Time
DateType
Date/Time
TimeType
Date/Time
DurationType
Date/Time
DecimalType
Decimal
DoubleType
Decimal
IntType
Decimal
LongType
Decimal
ShortType
Decimal
FloatType
Decimal
StringType
Text

Important: Always map ServiceCenter date / time fields to the XML schema dateTime or to one of
the related XML schema date or time types. Otherwise these fields will cause errors when you
consume the service
What methods do I need?
By default, any operation that is a part of the Document Engine for a table can be available in the
table’s Web Service. If you need additional methods, add them to the Document Engine first so that
ServiceCenter has a process to follow when performing them. If you have methods in the Document
Engine that you do not want exposed, delete them from the allowed actions array in the extaccess
table.
Note: The only Web Services methods that can be customized in ServiceCenter via display actions
and Process records are methods that modify data in ServiceCenter, such as the add, update, and
delete methods. Retrieving records is always done automatically via the SOAP API based on record
selection criteria. Manipulation of the data that is written back to ServiceCenter must be done by the
Web Service application that consumes the ServiceCenter data.
Are there any security considerations?
After you have exposed data over the Web, any client consuming the WSDL you are publishing has
access to that data. If there are certain fields that you want to restrict from specific clients, create a
different WSDL with those fields removed and have these clients consume that data.
15

Example: Publishing data from the currency and curconvert files
In this example, we prepare the data from the currency and curconvert files for use by other
applications via a Web Service. The examples in this document build on each other and must be
executed in the same order in which they appear.
Preparation step: Create a new dbdict called “pricelist”
The pricelist file will be used to store how much an item costs in local and foreign currency.
1.
Go to System Definition, right-click Table, and click New Table.
2.
Enter pricelist in the Table Name field and click OK.
3.
Click Add, Delete or Edit Fields and Keys
4.
Click New Field and enter the following information:
Field name: item.description
Field Type: text
5.
Click New Field and enter the following information:
Field name: price.usd
Field Type: decimal
6.
Click New Field and enter the following information:
Field name: price.foreign
Field Type: decimal
7.
Click New Field and enter the following information:
Field name: currency.foreign
Field Type: text
8.
Click New Field and enter the following information:
Field name: date.entered
Field Type: Date/Time
9.
Click Save
10.
The unique key for this file is “id." To fill this field automatically, you add a counter record. Go to
Database Manager, enter counters in the file and format fields, and enter the following
information:



11.
Click Add to add the counters record. Now the unique id field will be automatically generated.
12.
To create a format called “pricelist,” use Forms Designer Wizard and add all fields but
sysmodtime, sysmodcount and sysmoduser to the new format.

16


Creating Objects, States and Processes for the currency files
To be able to create new actions, you define a Document Engine Object, a State, and appropriate
Processes. Because no additional actions will be defined against the currency file, you do not have
to create Document Engine settings for it. In the Document Engine, enter the following information:
1.
Create an Object record for the curconvert file as shown below:


2.
Click Add to save the record.
3.
Create an Object record for the pricelist file as shown below:


17

4.
Click Add to save the record.
5.
Create a default State for the curconvert Object named curconvert.view as shown below:


6.
Click Add to save the record.
7.
Create a default State for the pricelist Object named pricelist.view as shown below:


8.
Click Add to save the record.
Creating the actions in the Document Engine
Next you add the following actions against the curconvert and pricelist files that will be
available from the Web Service. Currency records should be added, updated, or deleted only;
which are the standard actions that are already available. This example:
• Uses a Web Service to retrieve the current conversion rate for any currency against the US
Dollar (USD).
• Calculates how much a specified amount in a foreign currency represents in USD, and
updates the pricelist. (A new file is added for this example.)
The actions are already listed in the State records we created in the previous section. First you create
the displayscreen, then the displayactions, and finally the Process records required to execute the
actions.
1.
Create a displayscreen named curconvert.view as pictured below:

18



2.
Create the displayscreen for pricelist.view as shown below:



3.
Add a displayoption for the action that retrieves currency conversion rates from a Web Service
and adds the information to the curconvert file:

19



4.
Click Add to save.
5.
Add a displayoption that calculates how much a specified amount in a foreign currency represents
in US Dollars, and add the information to the pricelist file



6.
Click Add to save.

To define the Process that retrieves the currency conversion rate from a Web Service and adds the
information to the curconvert file, follow these steps:
7.
On the Initial JavaScript Tab enter:

var curr_code=system.vars.$L_file.currency_code;
system.vars.$G_USDConvRate=system.library.CurrencyConvertorRUN.GetCurren
cies(curr_code,
"
USD
"
);




8.
On the RAD Tab enter the following initialization expressions

rate in $L.file=$G.USDConvRate
date in $L.file=tod()
$L.bg=true
$L.obj.name={"curconvert"}

20

9.
Make a call to the se.base.method RAD application that performs basic actions to the record, such
as updates or in our example an add, as shown below:



10.
Click Add to add the new Process record.
11.
Define a Process that calculates how much a specified amount in a foreign currency represents in
US Dollars, and stores this information in the pricelist file: Enter the following statements lines
in the initial expressions:

$L.rate=jscall("CurrencyConvertorRUN.GetCurrencies", currency.foreign in
$L.file, "USD")
price.foreign in $L.file=price.usd in $L.file*val($L.rate, 1)
date.entered in $L.file=tod()

12.
Fill in the RAD tab as shown below:



Preparing the extaccess records
The following steps can be used to publish a ServiceCenter table as a Web Service.
1.
Click Menu Navigation -> Utilities -> Tools -> Web Services -> External Access.
2.
In the Name field, type the name of the ServiceCenter table you want to publish as a Web
Service.
3.
In the Service Name field, type the name of the Web Service that you want to use to publish this
table. You can reuse the same Web Service name to publish multiple tables, but you can only
publish a table as part of one Web Service at a time. The name you type for this field becomes the
alias name for the service, and becomes part of the Web Service URL. So, if you type MyService
for the service name, then the WSDL you are publishing would be called MyService.wsdl. The
name cannot contain URL-reserved characters such as spaces, slashes, or colons.
4.
In the Object Name field, type the name you want to use to identify the table. This name becomes
the alias name for the table and becomes part of the Web Service WSDL. For example, if you type
Mytable for the object name, then the SOAP operations for this table include Mytable as part of the
WSDL element, such as UpdateMytable, CreateMytable, and DeleteMytable.

21

Note: The name cannot consist of XML-reserved characters such as brackets (< and >), colons (:),
or quotation marks (" and ’). A best practice is to use an Object Name that is identical to the
Name and never contains “camel case” (where the name contains compound words or phrases that
are joined without
spaces
, and each word is
capitalized
within the name). Doing so causes an issue
indicating that the filename is incorrect or missing when calling the Web Service via ServiceCenter.
In some tools, you can modify the XML to include the filename in the SOAP body request as a
workaround. However, ServiceCenter and some other tools do not allow modifications.
Your Web Service is now ready to be consumed by a custom client. Windows
®
and Web clients are
unaffected by changes you make to the extaccess table. Windows and Web clients always use the
operator's application profile to determine which tables the user can access and which actions the
user can perform.
5.
In the Allowed Actions array, select the ServiceCenter Document Engine display actions you want
to enable globally for this table. Each table has its own set of allowable display actions that are
defined in the ServiceCenter Document Engine. Enabling or disabling the display actions from this
array determines only whether the display action is available through the Web Services API.
ServiceCenter still validates the operator credentials supplied with each Web Service request to
ensure that the operator has privileges to perform the display action. Click the array field to see a
list of allowable display actions for the table you select.
6.
In the Action Names field, type the name you want to use in the Web Services API to identify
the Document Engine display actions for this table. The name you type for this field becomes the
alias name for the display action, and becomes part of the Web Service WSDL. For example, if
you type Create for the add action of the mytable object, then the WSDL operation becomes
CreateMytable and the WSDL message is CreateMytableRequest. The name cannot consist
of XML reserved characters such as brackets (< and >), colons (:), or quotation marks (" and ’).



7.
Click the Data Policy tab and view the fields that are available for the table you are exposing.
The Exclude field should be set to true for any fields you want to keep out of the Web Service. If
you want the field exposed, set the Exclude field to false.
8.
Set the API Caption field to give an alias name to the API field. This alias name will appear in the
SOAP API.
9.
Set the API Data Type field to the appropriate XML data type for the field it represents:

22



10.
Click Add.
11.
Next create an external access definition record for the curconvert file as depicted below:





12.
Click Add to add the record.
13.
Create an external access definition record for the pricelist file as shown below:



23



14.
Click Add to add the record and restart the ServiceCenter server.
Consuming a ServiceCenter Web Service
A ServiceCenter Web Service can be consumed by a custom client or by an application that directly
consumes Web Services, such as ServiceCenter or Connect-It.
A Web Service development tool kit that can generate a complete Web Service application from a
.wsdl file is required to create a custom client that can access the ServiceCenter Web Service. A
good understanding of Web Services and SOAP versions 1.1 or 1.2 is also recommended.
There are several Web Services development tool kits that you can use to develop custom Web
Services clients.
• Microsoft Visual Studio
®
.NET
• Systinet WASP™
• Glue
• Apache Axis
• Sun

Web Services Developer Pack
Note: ServiceCenter users and application designers can choose any third-party Web Services
development tool kit. However, ServiceCenter publishes only the WSDL files for the Web Service.
Troubleshooting the client application is the responsibility of the application developer, and outside
the scope of ServiceCenter Customer Support.
Use the steps below as a guide to creating your custom Web Service client.
1.
Publish the ServiceCenter tables that you want your client to access. You can use the
ServiceCenter Web Services API out-of-the-box or customize the Web Services to meet your needs.
2.
Obtain a Web Services client development tool that can create a complete Web Service
application, such as Microsoft .NET or Apache Axis, or obtain a tool that generates a complete
Web Service application by evaluating the target WSDL file, such as GotDotNet
WebServiceStudio.
3.
Browse to the URL of your ServiceCenter server and download the WSDL files for the services you
want your custom clients to use. Use your Web Services client development tool to browse the
WSDL and determine which features you want your custom client to use. The URL of your server
must include the listener port and the Web Service name. For example in SC 6.1 or SC 6.2 classic
mode,

http://<scserver>:<listener port number, default
12670>/IncidentManagement.wsdl

24

connects to the scserver host on port 12670 and requests the IncidentManagement WSDL.

In ServiceCenter 6.2 servlet mode, the wsdl for Incident Management can be found by entering

http://<servername>:<httpPort or loadBalancer
port>/sc62server/PWS/IncidentManagement.wsdl

4.
Use your Web Services client development tool to generate the programming language client
code (classes) that will serve as a proxy for the ServiceCenter Web Services API. Tools such as
.NET wsdl.exe or Axis wsdl2java can convert WSDL to the code base you choose for your
client code. Your custom Web Services client invokes the client code rather than the WSDL
directly.
5.
Write a client application in the appropriate language of your client development tool. For
example, .NET requires either Microsoft Visual C# or Visual Basic
®
, and Axis requires Java.
Retrieving data from ServiceCenter
The ServiceCenter online documentation is a valuable resource for implementing and troubleshooting.
The following items are known issues and workarounds that need to be considered when building a
custom Web Service client application.
• ServiceCenter currently returns only one record at a time as a GetResponse.
• If there are no records returned from a request, no body section appears in the response
message.
• To query data in a file, use a Get or GetListKeys request followed by a GetListData request.
Retrieve methods usually available and when to use them
• Retrieve<FileName> — Used if only one record will be returned. Throws a fault if
multiple records are returned.
• Retrieve<FileName>KeysList — Retrieves the list of unique keys (which does not have
to be the unique key of the ServiceCenter dbdicts). The list can either be passed as an array
to the Retrieve<FileName>List method, or looped through to pass to the
Retrieve<FileName> method.
• Retrieve<FileName>List — Retrieves a list of records with information that was gathered
either in the Retrieve<FileName>KeysList method or by passing in a query directly
through the instance block. This method expects an array of keys unless the query approach
is used.
There are different approaches to retrieving a list of records. When developing a custom client there
are actually two separate methods that can be used to retrieve list data.
The first approach uses these steps:
1.
Send the data query (such as <open.time>&gt;6/30/05</open.time>) to the
RetrieveListKeys method.
2.
The result is a list of records where each record contains only the “primary key” (such as Incident
ID) for those records that match the query.
3.
You can either provide the list to the RetrieveList method and receive all records defined by
the list in a single XML document, or loop through the list, one record at a time, calling Retrieve
once for each record by key.
The second approach uses these steps:
25

1.
Send the data query (such as <open.time>&gt;6/30/05</open.time>) directly to the
RetrieveList method. Place the query in the “<instance>” block instead of the “<keys>”
block.
2.
This single method call returns the entire result set (all fields for all records matching the query) in a
single XML response.
Note: The second approach returns the entire query result set in one method call. If the result set is
large you should use the first approach to increase performance.
Retrieving data from a ServiceCenter file rather than a Service
Note: When using a WSDL for a single table such as contacts, it is best to request the WSDL for the
alias name defined in extaccess, such as "Contact" (singular form, upper-case “C”) rather than for
contacts (the actual file name).
For example:
http://localhost:12670/Contact.WSDL
will ensure that you get the ServiceCenter 6.1 style
WSDL and API. If you request the WSDL with the actual file name, you will retrieve the 6.0 style
WSDL and API.
The only reason you would write a new application using the ServiceCenter 6.0 SOAP API is if you
must interoperate with a 6.0 server, or with a 6.1 server running 6.0 applications.
Example: Retrieving ServiceCenter price lists into a text file using
Connect-It
To set up Connect-It to work with Web Services, the Java Configuration must be set first.
1.
Click Java –> Configure JVM ….
2.
Check the checkbox labeled Specify the JRE to use.
3.
In the path of the JNI dynamic library of the JRE root directory (JavaHome) enter the path to your
JRE, for example c:\j2sdk1.4.2_05\jre.
4.
In the path of the JNI dynamic library of the JRE enter the path to the jvm.dll including the file
name, such as c:\j2sdk1.4.2_05\jre\bin\client\jvm.dll
5.
Save the settings and restart Connect-It for the settings to take effect.
6.
Once Connect-It is configured to work with Web Services, you can create the ServiceCenter Web
Services Connector with the following connection parameter settings. (All other settings remain the
defaults.)

Server name: <server name>:<listener port number>
Service name: CurrencyManagement
Login: falcon

7.
Click Finish to save the changes made to the new connector.
8.
In our example, the Web Service simply fills information into a delimited text field. The settings for
that connector are as follows:

Processing Mode: write
Connection protocol: Local / network files

Enter a folder name and decide whether to create a separate file for each record retrieved or write
all records into one file.

On the next screen, decide whether to keep the old files or delete and create a new one with each
run.

26

Enter the path to the descriptor file (see below) or create a new descriptor file.

9.
Click Finish to create and save the connector.
To create a description file for the text output file (comma delimited text in our example), the following
sample code shows a simple .dsc file that can be used for retrieving pricelist information.
{ TextFileFormat SCPriceList
Extension=
FormatType=Delimited
EscapeChar="\\"
Quote="\""
Extracolumn=1
WriteColumn=1
Delimiter=,
{ String "Item Description"
UserType=Default
}
{ Double "Price USD"
UserType=Monetary
}
{ Double "Price Foreign"
UserType=Monetary
}
{ String "Currency Foreign"
UserType=Default
}
{ TimeStamp "Date Entered"
UserType=TimeStamp
}
}
Finally the source (Web Services) data and the target date (Delimited Text file) must be mapped as
shown below:



10.
Because Web Services need to be prompted to produce output, another text file connector must be
created that helps create the request sent to the Web Service. This text file connector is defined as
follows:

Processing Mode: read
Connection Protocol: Local/Network files
Location: Read files, file name: c:\temp\connectitinput.txt (see below for content of file)

27



11.
Upon successful processing, leave the file in the folder.
12.
Use this .dsc file. Enter c:\temp\input.dsc and click Find to create or modify a description
file.
13.
Select a document type: Click the down arrow and enter PriceListInput.
14.
Click Next.
15.
Select a file for the preview. Accept the default c:\temp\connectitinput.txt and click Next.
16.
Enter the information shown on the next screen:



17.
Click Next.
18.
Enter the information shown on the next screen:

28



19.
Click Finish.
20.
Click Finish to create and save the connector.
21.
Now create a mapping between this text file and the ServiceCenter Web Service by connecting
the two. The mapping is shown below:



22.
Click Produce Now (the F5 button) to fill information from the pricelist file in ServiceCenter
into a delimited text file via Web Services.
Example: Getting currency information and pricelist information from
another ServiceCenter system
This example retrieves currency information from the curconvert file and uses the Web Service to
add new records to the pricelist file based on the current conversion rates.
1.
Click System Navigator –> Menu Navigation –> Utilities –> Tools –> Web Services
and click Run WSDL2JS.
2.
In the “Please enter the URL for the WSDL file” field, enter the following:

http://<servername>:<port number>/CurrencyManagement.wsdl

3.
Click Proceed -> Add to create the CurrencyManagement JavaScript record in the ScriptLibrary.
29

4.
Because authentication is necessary for Web Services to consume ServiceCenter data, the newly
created Service Object needs to be changed to define the userID that is used to sign on to
ServiceCenter. Modify the code as shown below.

Note: The namespace specified in “this.location” does not have to be resolvable.

function CurrencyManagement( )
{
this.location = new String( "http://localhost:12670/scserver61/ws" );

this.user = "falcon";
this.password = null;
this.connectTimeOut = 10;
this.sendTimeOut = 10;
this.recvTimeOut = 10;
this.soapEnvelope = null;
this.soapBody = null;
this.soapHeader = null;
this.attachments = new Array();
this.resultXML = null;
this.invoke = invoke;

5.
Now that the Script has been added to the ScriptLibrary, you write another JavaScript that can be
used to retrieve the currency conversion data. Enter the JavaScript code as listed below:

function RetrieveCurrencyConversion(RootCurrency, ForeignCurrency)
{
var CurrConvSvc = new
system.library.CurrencyManagement.CurrencyManagement();

var retrieveReq = new
system.library.CurrencyManagement.RetrieveCurrencyConversionList();

retrieveReq.newInstance();

retrieveReq.keys[0].RootCurrencyCode.setValue(RootCurrency);
retrieveReq.keys[0].CurrencyCode.setValue(ForeignCurrency);

try
{
var retrieveResp = CurrConvSvc.invoke(retrieveReq);

if ( retrieveResp.isFault() )
{
throw( "SOAP Fault: " + retrieveResp.faultstring.getValue() );
}

return retrieveResp.instance;
}
catch( err )
{
return( "Error! " + err );
}
}

// Below an example on how to call the function and retrieve all Exchange
// Rates stored for USD to EUR conversion. This looping through the
records
// will have to be done from the calling application / java script when
// calling the RetrieveCurrencyConversion function.

var instanceArrayObj = RetrieveCurrencyConversion("USD", "EUR");

var numRecs = instanceArrayObj.length;

var i;
30


for ( i = 0; i < numRecs; i++ )
{
print( instanceArrayObj[i].ExchangeRate.getValue() );
}
6.
Create a JavaScript in the same ScriptLibrary record that reads a pricelist record and then
creates a new record with updated foreign price and date. Enter the Java Script shown below:

function AddUpdatedPriceList(ID, PriceUSD, CurrencyForeign)
{
var PriceListSvc = new
system.library.CurrencyManagement.CurrencyManagement();

var UpdateReq = new
system.library.CurrencyManagement.ConvertAddPricelistPricelist();

UpdateReq.model.keys.id.setValue(ID);
UpdateReq.model.instance.PriceUSD.setValue(PriceUSD);

UpdateReq.model.instance.ForeignCurrencyCode.setValue(CurrencyForeign);

try
{
var updateResp = PriceListSvc.invoke(UpdateReq);

if ( updateResp.isFault() )
{
throw( "SOAP Fault: " + updateResp.faultstring.getValue() );
}

return updateResp.model.instance;
}
catch( err )
{
return( "Error! " + err );
}

}
var ResRecord = AddUpdatedPriceList(1, 30, "EUR");

Using the ServiceCenter Web Services examples in the RUN
directory
Both the AxisSample and the DotNetSample directories contain documents with setup instructions.
In AxisSample this document is called readme.txt. In DotNetSample the document is called
WebServices README.doc.
The AxisSample\bin directory contains a selection of batch files that can be run directly, if JDK 1.4
or higher and Apache Ant are both installed on the machine. The DotNet samples have to be
compiled before running.
To run an example of closing an existing Incident Record from the DotNetSample directory:
1.
Follow the instructions in the WebServices README.doc file located in the DotNetSample
directory.
2.
Enter the following in the Visual Studio .Net Command prompt to close an incident:
C:\Program Files\ServiceCenter Server\webservices\sample\DotNetSample\
DotNetSample\bin\Debug>dotnetsample -example CloseIncident host localhost
port 61170 -incidentId IM1001 -closeCode "User Closure" -resolution
"I want to see if this works"
31

Note: If the username and password are not entered specifically, they default to “falcon” with no
password, and the following appears in the sc.log file:
2984 05/19/2006 10:17:29 Process 2984 started on socket 216.
2984 05/19/2006 10:17:29 Process scenter 6.1.1.0 (0082) System: 61170
(0x7d781a00)
2984 05/19/2006 10:17:29 on PC running Windows XP Professional (5.1
Build 2600) from xxxxx (127.0.0.1)
2984 05/19/2006 10:17:29 connected to SOAP client at 127.0.0.1:4072
2984 05/19/2006 10:17:29 Attaching to resources with key 0x7d781a00
2984 05/19/2006 10:17:29 Starting SOAP server
2984 05/19/2006 10:17:29 tpzsoap: soap_bind succeeded. New listening
port=4073
2984 05/19/2006 10:17:29 Authentication failure - No "Authorization:
Basic" header was supplied, or it contained a zero-length userid
2984 05/19/2006 10:17:29 Exception occurred for method Close and XML
request <CloseIncidentRequest
xmlns="http://servicecenter.peregrine.com/PWS"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
><model><keys><IncidentID>IM1001</IncidentID></keys><instance><IncidentID
xsi:nil="true" /><Category xsi:nil="true" /><OpenTime xsi:nil="true"
/><OpenedBy xsi:nil="true" /><Severity xsi:nil="true" /><UpdatedTime
xsi:nil="true" /><PrimaryAssignmentGroup xsi:nil="true" /><ClosedTime
xsi:nil="true" /><ClosedBy xsi:nil="true" /><ClosureCode>User
Closure</ClosureCode><ConfigurationItem xsi:nil="true" /><Location
xsi:nil="true" /><AssigneeName xsi:nil="true" /><Contact xsi:nil="true"
/><AlertStatus xsi:nil="true" /><ContactLastName xsi:nil="true"
/><ContactFirstName xsi:nil="true" /><Company xsi:nil="true"
/><BriefDescription xsi:nil="true" /><TicketOwner xsi:nil="true"
/><UpdatedBy xsi:nil="true" /><IMTicketStatus xsi:nil="true"
/><Subcategory xsi:nil="true" /><SLAAgreementID xsi:nil="true"
/><SiteCategory xsi:nil="true" /><ProductType xsi:nil="true"
/><ProblemType xsi:nil="true"
/><ResolutionFixType>permanent</ResolutionFixType><attachments
xsi:nil="true" /></instance></model></CloseIncidentRequest>
2984 05/19/2006 10:17:29 soap_serve - Caught XML API exception
scxmlapi(20) - Authentication failure
2984 05/19/2006 10:17:29 Sending 401 Not Authorized challenge
2984 05/19/2006 10:18:03 User falcon has logged in and is using a
Floating license (1 out of a maximum 10)
2984 05/19/2006 10:18:06 Activity record added.
2984 05/19/2006 10:18:06 Triggers have been turned on
2984 05/19/2006 10:18:06 Incident IM1001 has been closed by falcon.
Related calls will be processed normally.
Troubleshooting
The combination of debugging tools and information gathered from SOAP faults usually helps you
find the root cause of an issue easily. Unfortunately, not all Web Services give sufficient SOAP fault
messages, which makes debugging the issue more challenging.
What to do if the WSDL2JS utility fails
The WSDL to JS utility will read the provided wsdl with all incorporated schema definitions and
creates a JavaScript record in the ServiceCenter ScriptLibrary that can then be called from the custom
written JavaScript to consume the external Web Service. If the code generated by WSDL2JS is
incorrect or incomplete, contact Customer Support for a new unload of the utility. If the issue is still
not solved with the latest version of the WSDL2JS utility, send the wsdl and all imported / invoked xsd
schemas to customer support together with an unload of the generated JavaScript record. It is very
important that the location of the xsd files that are imported or invoked from the wsdl is set correctly,
otherwise the wsdl2js utility will generate incomplete code.
32

Important: If you are using a newer WSDL2JS utility (or SOAP ScriptLibrary record), it is likely that
the generated JavaScript records will have to be re-generated and the calling JavaScripts have to be
re-compiled.
What happens if an exposed table is tailored?
The WSDL for a service should not change automatically as a result of making tailoring changes such
as adding a new field to a table. Only if you include the new field in the Web Services API by
checking a box in the System Definition UI is the WSDL supposed to change.
If you change the alias name by which a field is exposed in a Web Service, you are going to have to
modify and recompile any SOAP client applications which reference this field. You can rename the
internal ServiceCenter field names, even for fields which are exposed via Web Services, without
impacting deployed Web Services, as long as you do not change the alias name by which the field is
known to Web Services.
Finally, if you add a new field, and make the new field a required field, and you have previously
deployed Web Services applications which do not populate this field, you must provide tailoring in
the server which will generate a valid default value for the field if not specified. Otherwise, inserts
and updates via Web Services will fail because the new field has not been populated when the
record goes through validation.
Debugging
Three parameters are most frequently used: debughttp, RTM:3, and debugdbquery:999.
debughttp
Enter debughttp in the server sc.ini file and restart the client to invoke the debugging parameter.
For consuming Web Services, the debughttp parameter creates two files in the ServiceCenter Server
RUN directory, outbound_http.log and outbound_test.log, and writes additional information
into the sc.log file.
An excerpt of the outbound_http.log file follows. (See the red areas for the error messages that
were captured.)
POST /scserver61/ws HTTP/1.0
Host: lp84564igeist:61170
User-Agent: gSOAP/2.2
Content-Type: text/xml; charset=utf-8
Content-Length: 1128
Connection: Close
Accept-Encoding: gzip, deflate
Authorization: Basic ZmFsY29uOg==
SOAPAction: "Retrieve"

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ns="http://servicecenter.peregrine.com/PWS"><soap:Body><RetrieveCur
rencyConversion attachmentInfo="false" attachmentData="false"
ignoreEmptyElements="true"
xmlns="http://servicecenter.peregrine.com/PWS"><model query=""><keys
query=""><sortcode type="Decimal" mandatory="false"
readonly="false"/><CurrencyCode type="String" mandatory="false"
readonly="false">EUR</CurrencyCode><Date type="DateTime"
mandatory="false" readonly="false"/><RootCurrencyCode type="String"
mandatory="false" readonly="false">USD</RootCurrencyCode></keys><instance
query="" uniquequery="" recordid=""><CurrencyCode type="String"
mandatory="false" readonly="false"/><Date type="DateTime"
mandatory="false" readonly="false"/><ExchangeRate type="Float"
mandatory="false" readonly="false"/><RootCurrencyCode type="String"
mandatory="false"
33

readonly="false"/><attachments></attachments></instance><messages></messa
ges></model></RetrieveCurrencyConversion></soap:Body></soap:Envelope>HTTP
/1.1 500 Internal Server Error
Pragma: thinktime="0"
Server: gSOAP/2.2
Cache-Control: no-cache
Content-Type: text/xml; charset=utf-8
Content-Length: 657
Connection: Close
Set-Cookie: SessionId=16.95.106.150:3655;Version=1

<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-
ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-
ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://servicecenter.peregrine.com/PWS"><SOAP-ENV:Body><SOAP-
ENV:Fault><faultcode>SOAP-ENV:Server</faultcode><faultstring>scxmlapi(26)
- Get request found more than one
record</faultstring><detail><appFaultCode>26</appFaultCode><appFaultStrin
g>scxmlapi(26) - Get request found more than one
record</appFaultString></detail></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-
ENV:Envelope>POST /scserver61/ws HTTP/1.0
Host: lp84564igeist:61170
User-Agent: gSOAP/2.2
Content-Type: text/xml; charset=utf-8
Content-Length: 1109
Connection: Close
Accept-Encoding: gzip, deflate
Authorization: Basic ZmFsY29uOg==
SOAPAction: "RetrieveList"

RTM:3 and debugdbquery:999
Sometimes the Web Service itself is working correctly, but actions performed by the Document Engine
within ServiceCenter are not performing as expected. The RTM:3 and debugdbquery:999
parameters can expose such issues that occur within the application layer of ServiceCenter. The
debugging information produced by these parameters can be found in the sc.log file in the
ServiceCenter server RUN directory.
Testing your WSDL using .NET Web Service Studio
The .NET Web Service Studio is a free software tool that can be downloaded from
http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=65a1d4ea-0f7a-41bd-8494-
e916ebc4159c
.
1.
Enter the WSDL EndPoint (which is the URL that points to the WSDL) and click Get to get the list of
methods available for this WSDL.
34


2.
Click the Invoke tab, select the method to test, and then check the input fields, both for values
that were filled with incorrect information that needs to be changed and for criteria that need to be
added for a successful test.
3.
Click Invoke.
4.
An error message is displayed because the “not authorized” error occurred. Click Continue and
click the Request / Response tab.


************** Exception Text **************
System.Reflection.TargetInvocationException: Exception has been thrown by
the target of an invocation. ---> System.InvalidOperationException:
Client found response content type of 'text/html; charset=utf-8', but
expected 'text/xml'.
The request failed with the error message:
--
Not Authorized
--.

5.
On the left hand side of the Request / Response tab is the authentication information. Enter the
BasicAuthUserName and change the following settings from False to True:

• AllowAutoRedirect
• AllowWriteStreamBuffering
• PreAuthenticate
• UseCookieContainer
• UseDefaultCredential
Note: The information entered on the Request/Response tab is not stored and has to be re-entered
frequently.
6.
Click Send.
In the lower right, the response from the Server will be displayed. In the example shown below, it is
the key value for the record that matched the retrieve criteria.
35


Advanced Troubleshooting
How to troubleshoot a Web Service that is behind a closed firewall
Sometimes it may be necessary to troubleshoot a Web Service that is not available. To do so, we
can check whether a wsdl file that is stored on the local machine works using test data.
Step 1: Test the WSDL2JS
1.
Store the wsdl file locally on the server.
2.
Click Utilities –> Tools –> Web Services. Click Run WSDL to JS and enter the following:

file://<fully qualified path to the file>.wsdl

3.
Click Proceed.
If the JavaScript file for the Web Service is generated without error messages and ends with …
// Ensure that material in lib.SOAP is available

lib.SOAP.init();
/// End ----------------
… then the WSDL to JS program was able to interpret the wsdl file correctly.
To correctly write the JavaScript functions to call this Web Service and generated Java Script, check
the generated Java Script for the function you want to use, in this case:
this.SOAPOperations[ "RetrieveIncident" ] = new soap_Operation(
"RetrieveIncident", "Retrieve", "document", "RetrieveIncidentRequest",
"RetrieveIncidentResponse" );
The request can be found within that line and refers to the request function further down:
function RetrieveIncidentRequest( )
{
this.$$nsPrefix = "ns";
36

this.$$attributes = new Array();
this.$$xmlNames = new Array();
this.$$objNames = new Array();
this.$$minOccurs = new Array();
this.getName = getName;
this.getXmlName = getXmlName;
this.setContent = setContent;
this.addContent = addContent;
this.getContent = getContent;
this.isFault = isFault;
this.$$elementChildren = new Array();
this.$$name = "RetrieveIncidentRequest";
this.$$xmlNames[ "RetrieveIncidentRequest" ] =
"ns:RetrieveIncidentRequest";
this.attachmentInfo = new Boolean();
this.$$attributes.push( "attachmentInfo" );
this.attachmentData = new Boolean();
this.$$attributes.push( "attachmentData" );
this.ignoreEmptyElements = new Boolean("true");
this.$$attributes.push( "ignoreEmptyElements" );
this.xmlns = new String("http://servicecenter.peregrine.com/PWS");
this.$$attributes.push( "xmlns" );
this.model = new RetrieveIncidentRequest_IncidentModelType();
this.$$elementChildren.push( "model" );
}
Step 2: Test the request
Once the automatically generated JavaScript code was saved (and userID information was added if
necessary), write a calling JavaScript to execute the Web Service. The following is a simple example
code for IncidentManagement record retrieval:
function RetrieveIncident(incident_id)
{
var IncMgmtSvc = new
system.library.IncidentManagement.IncidentManagement();

var retrieveReq = new
system.library.IncidentManagement.RetrieveIncidentRequest();

retrieveReq.model.keys.IncidentID.setValue(incident_id);

try
{
var retrieveResp = IncMgmtSvc.invoke(retrieveReq);
if ( retrieveResp.isFault() )
{
throw( "SOAP Fault: " + retrieveResp.faultstring.getValue() );
}
return retrieveResp.model.instance;
}
catch( err )
{
return( "Error! " + err );
}
}

retVal=RetrieveIncident("IM1001");

print("Testing the result" + retVal.IncidentID.getValue())
1.
To test the request, enter debughttp in the sc.ini file and restart the client.
2.
If the file outbound_http.log exists in the server’s RUN directory, remove it or remove its
contents so that there will be a fresh file to read.
3.
Go into the calling JavaScript and click Execute. You will most likely get an error message
because the Web Service you are trying to reach is not available.
37

4.
After the execution is complete, open the outbound_http.log file and search for the following:

POST /scserver61/ws HTTP/1.0
Host: lp84564igeist:61170
User-Agent: gSOAP/2.2
Content-Type: text/xml; charset=utf-8
Content-Length: 2680
Connection: Close
Accept-Encoding: gzip, deflate
Authorization: Basic ZmFsY29uOg==
SOAPAction: "Retrieve"

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ns="http://servicecenter.peregrine.com/PWS"><soap:Body><ns:Retrieve