You are on page 1of 13

TestTrack_SOAP_SDK_Tutorial__NetBeans_Java_(JAXRPC)

Works with TestTrack 2008.1


Works with NetBeans 6.1
If you would like to take advantage of the TestTrack SOAP SOAP based SDK, you have at your disposal
several options as to which language to use. Using Java can be tricky since you first must find an IDE that
allows you to work with web services and can build Java classes from the WSDL file.

While Axis is a very powerful and popular tool, there are some parsing issues with Axis version 1.4 that can
make it very frustrating and as of the time of this writing, the latest version of Axis2 is not able to create the
Java classes from TestTrack WSDL.

A relatively easy way to create SOAP applications using Java is with NetBeans. The following is a tutorial
that will take you step by step on how to create a simple Java application that you can use to get a list of
defects, updates a defect, among other actions.

NOTE: This is not a tutorial on how to use NetBeans or write Java applications. The sole purpose of this
article is to show how to use the TestTrack SOAP based SDK in NetBeans. You may find a different and
maybe better way to use NetBeans for developing SOAP applications.
This is meant as an example only and Seapine does not offer support for this.

Contents
1 Don't want to use NetBeans?
2 The environment
3 Creating the project
4 Setting up the web service interface
4.1 Handling a known issue
4.2 Editing the WSDL file
5 Handling a requirement
6 Creating the web service client
6.1 Getting the files in the
package
6.2 Editing the classes
7 Writing Code
7.1 Invoking a web service
operation
7.2 Setting the ttsoapcgi url
7.3 Sample Methods
7.4 Logging into a project
7.5 Getting a defect list array
(CRecordListSoap)
7.6 Get defect for edit
7.7 Save Defect
8 Download

Contents

TestTrack_SOAP_SDK_Tutorial__NetBeans_Java_(JAXRPC)

Don't want to use NetBeans?


If you do not want to work with NetBeans, you can just download the Generated Java Classes. Simply import
the needed Jar files into your project using your favorite IDE.

The environment
The following example uses TestTrack 2008.1.2 and NetBeans IDE 6.1 (Build 200805300101). Older
versions of TestTrack or NetBeans should also work.
Screenshots included in this article are of NetBeans or TestTrack in a Windows environment.

Creating the project


Creating the project is very straight forward. In NetBeans, select File > New Project.... The New Project
dialog appears. The New Project dialog consists of two sections:

1. Choose Project Under Categories select Java and under Projects: select Java Application.

Click on Next. This takes you to the second section.

2. Name and Location Under Project Name: enter the name of the project. In this example we will use the
name "ttSoapSample". You can leave the location as is or you can change it to a different location. Leave the
box checked next to Create Main Class. Optionally you can leave the Set as Main Project box checked.
This really should only be left checked if this is the project you are going to be spending most of your time.

Figure 1 New project dialog

Setting up the web service interface


The next major step is to step up an interface with the TestTrack SOAP server. NetBeans can create a web
service client based on a WSDL file. While this works for the most part, there are a couple of things you must
do to get it to work properly.
Don't want to use NetBeans?

TestTrack_SOAP_SDK_Tutorial__NetBeans_Java_(JAXRPC)
NOTE: You can always just download the Generated Java Classes.

Handling a known issue


The main issue is with the Web Service Client in NetBeans not handling dashes in the WSDL properly and
creating variables in Java with those dashes in the name which causes compile errors.

Other Java utilities like Axis remove the dashes when declaring the Java variables.

These variables are used mainly when creating a defect object. They are used both for the list of source code
files (CSCCFileRecord) and file attachments (CFileAttachment).
TestTrack 2010 note: In 2010, a new object called CFile was instroduced. This one must also be adjusted.
Here is a list of these variables:
CSCCFileRecord
mstrFileName
mstrFixedRevision
mdateFixedTimestamp
mstrType
mscriptOrder
mpFileData

CFileAttachment

mstrFileName
mstrArchiveName
mstrType
mscriptOrder
mstrScriptState

Setting up the web service interface

TestTrack_SOAP_SDK_Tutorial__NetBeans_Java_(JAXRPC)
Keep in mind that the dashes need only to be handled while processing Java code. When the XML file is built,
those variables will need to have dashes in them, as defined in the WSDL file.

This leaves you with two options:

1. Edit the WSDL file and remove the dashes for those variables, and then edit the XML serializer classes to
include the dashes when building the XML files.

2. Create the classes using the standard WSDL, let NetBeans complain about the syntax issues and manually
fix the variable names. There are about 100 edits required and you may have to do this every time the client
refreshes itself.
By far the easiest is to go with option #1 and that is what will be done in this example.

NOTE: This is only required if you need to build a defect, test case or test run object. If your application only
needs to retrieve a list of defects, for example, you do not need to worry about editing the SOAP serializer
classes.

Editing the WSDL file


NOTE: Make a backup copy of the ttsoapcgi.wsdl file before making any changes.
Open the ttsoapcgi.wsdl file with your favorite XML editor. Search for any "" characters and either replace
them with an underscore or just remove them from the variables listed above.
The first section you will see these variables in is:

<complexType name="CSCCFileRecord">
<complexContent>
<extension base="ttns:CItemWithDBRecordId">
<sequence>
<element name="mstrFileName" type="xsd:string" minOccurs="1" maxOccurs="1" nillable="false"
<element name="mstrFixedRevision" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="t
<element name="mdateFixedTimestamp" type="xsd:dateTime" minOccurs="0" maxOccurs="1" nillabl
<element name="mstrType" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
<element name="mscriptOrder" type="xsd:long" minOccurs="0" maxOccurs="1"/>
<element name="mstrScriptState" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="tru
</sequence>
</extension>
</complexContent>
</complexType>

After removing the dashes , it now looks like this:


<complexType name="CSCCFileRecord">
<complexContent>
<extension base="ttns:CItemWithDBRecordId">

Handling a known issue

TestTrack_SOAP_SDK_Tutorial__NetBeans_Java_(JAXRPC)

<sequence>
<element name="mstrFileName" type="xsd:string" minOccurs="1" maxOccurs="1" nillable="false"/
<element name="mstrFixedRevision" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="tr
<element name="mdateFixedTimestamp" type="xsd:dateTime" minOccurs="0" maxOccurs="1" nillable
<element name="mstrType" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
<element name="mscriptOrder" type="xsd:long" minOccurs="0" maxOccurs="1"/>
<element name="mstrScriptState" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true
</sequence>
</extension>
</complexContent>
</complexType>

The next section where you will find the variables is here:

<complexType name="CFileAttachment">
<sequence>
<element name="mpFileData" type="xsd:base64Binary" minOccurs="0" maxOccurs="1" nillable="tr
<element name="mstrFileName" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/
<element name="mstrArchiveName" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="tru
<element name="mstrType" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
<element name="mscriptOrder" type="xsd:long" minOccurs="0" maxOccurs="1"/>
<element name="mstrScriptState" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="tru
</sequence>
</complexType>

After doing the same with these variables, the section now looks like this:

</complexType>
<complexType name="CFileAttachment">
<sequence>
<element name="mpFileData" type="xsd:base64Binary" minOccurs="0" maxOccurs="1" nillable="tru
<element name="mstrFileName" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
<element name="mstrArchiveName" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true
<element name="mstrType" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
<element name="mscriptOrder" type="xsd:long" minOccurs="0" maxOccurs="1"/>
<element name="mstrScriptState" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true
</sequence>
</complexType>

Handling a requirement
The WSDL is rpc encoded and you will need to download the JAXRPC Web Service plugin for NetBeans.

Creating the web service client


Since we are going to need to edit some of the java files, we need to include them in the project. It is
recommended that you create a separate package to hold these files.
In this example, the package is named "testtrack_Interface" under the Source Packages folder.
While the project is selected, select File > New File. The New File dialog appears. Under Categories select
Web Services and then under File Types select Web Service Client.

Editing the WSDL file

TestTrack_SOAP_SDK_Tutorial__NetBeans_Java_(JAXRPC)
Click on Next.

The WSDL and Client Location appears. Choose the location of the WSDL file. If the WSDL file is located
on your machine, you may select "Local File" and browse for the file. If the file is on a web server, choose the
WSDL URL option.

In this example, the ttsoapcgi.wsdl is installed on the C:\inetpub\wwwroot\ folder on the same machine.
Therefore either Local File: (C:\inetput\wwwroot\ttsoapcgi.wsdl) or WSDL URL
(http://localhost/ttsoapcgi.wsdl) options are valid.

Next, select "JAXRPC Style" from the Client Side drop down. This selection will in turn enable you to
select the package to include the client in. Select the package you created to store the web service client files.

Click on Finish

Figure 2 New Web Service Client dialog


In the output pane you will see messages about the compile process. You may see warnings about WSI non
comforming operations. At the end you should see BUILD SUCCESSFUL.

Figure 3 Build output

Getting the files in the package


You will notice that if you now go into the testtrack_Interface package, it is still empty, eventhough you
specified to place the files in there and also the ttsoapcgiconfig.xml file in the METAINF.wsdl package
also references the testtrack_Interface package.

You must manually copy the files into this package.


Creating the web service client

TestTrack_SOAP_SDK_Tutorial__NetBeans_Java_(JAXRPC)
Browse to the folder where your project is stored and find the \build\generated\wsclient directory. There you
will see a folder with the pacakage name. Copy the folder and replace the empty folder with the same name
under the \src directory.
The package in NetBeans now shows all of the Java classes created by the Web Service Client.

Editing the classes


As mentioned earlier, the last thing we need to do is edit two files:
CSCCFileRecord_SOAPSerializer.java

CFileAttachment_SOAPSerializer.java
In each file you will find a section where it builds the section of the XML file for the file attachments and
source code files.

The portion of the CFileAttachment_SOAPSerializer file looks like this:

public class CFileAttachment_SOAPSerializer extends ObjectSerializerBase implements Initializable


private static final javax.xml.namespace.QName ns1_m_pFileData_QNAME = new QName("", "mpFileD
private static final javax.xml.namespace.QName ns3_base64Binary_TYPE_QNAME = SchemaConstants.
private CombinedSerializer ns3_myns3_base64Binary__byte_Base64Binary_Serializer;
private static final javax.xml.namespace.QName ns1_m_strFileName_QNAME = new QName("", "mstrF
private static final javax.xml.namespace.QName ns3_string_TYPE_QNAME = SchemaConstants.QNAME_
private CombinedSerializer ns3_myns3_string__java_lang_String_String_Serializer;
private static final javax.xml.namespace.QName ns1_m_strArchiveName_QNAME = new QName("", "ms
private static final javax.xml.namespace.QName ns1_m_strType_QNAME = new QName("", "mstrType"
private static final javax.xml.namespace.QName ns1_m_scriptOrder_QNAME = new QName("", "mscri
private static final javax.xml.namespace.QName ns3_long_TYPE_QNAME = SchemaConstants.QNAME_TY
private CombinedSerializer ns3_myns3__long__java_lang_Long_Long_Serializer;
private static final javax.xml.namespace.QName ns1_m_strScriptState_QNAME = new QName("", "ms

After making the changes, it looks like this:

public class CFileAttachment_SOAPSerializer extends ObjectSerializerBase implements Initializable


private static final javax.xml.namespace.QName ns1_m_pFileData_QNAME = new QName("", "mpFile
private static final javax.xml.namespace.QName ns3_base64Binary_TYPE_QNAME = SchemaConstants.
private CombinedSerializer ns3_myns3_base64Binary__byte_Base64Binary_Serializer;
private static final javax.xml.namespace.QName ns1_m_strFileName_QNAME = new QName("", "mstr
private static final javax.xml.namespace.QName ns3_string_TYPE_QNAME = SchemaConstants.QNAME_
private CombinedSerializer ns3_myns3_string__java_lang_String_String_Serializer;
private static final javax.xml.namespace.QName ns1_m_strArchiveName_QNAME = new QName("", "m
private static final javax.xml.namespace.QName ns1_m_strType_QNAME = new QName("", "mstrType
private static final javax.xml.namespace.QName ns1_m_scriptOrder_QNAME = new QName("", "mscr
private static final javax.xml.namespace.QName ns3_long_TYPE_QNAME = SchemaConstants.QNAME_TY

Getting the files in the package

TestTrack_SOAP_SDK_Tutorial__NetBeans_Java_(JAXRPC)

private CombinedSerializer ns3_myns3__long__java_lang_Long_Long_Serializer;


private static final javax.xml.namespace.QName ns1_m_strScriptState_QNAME = new QName("", "m

A similar section is found in the CSCCFileRecord_SOAPSerializer file:

public class CSCCFileRecord_SOAPSerializer extends ObjectSerializerBase implements Initializable


private static final javax.xml.namespace.QName ns1_recordid_QNAME = new QName("", "recordid")
private static final javax.xml.namespace.QName ns3_long_TYPE_QNAME = SchemaConstants.QNAME_TY
private CombinedSerializer ns3_myns3__long__long_Long_Serializer;
private static final javax.xml.namespace.QName ns1_m_strFileName_QNAME = new QName("", "mstrF
private static final javax.xml.namespace.QName ns3_string_TYPE_QNAME = SchemaConstants.QNAME_
private CombinedSerializer ns3_myns3_string__java_lang_String_String_Serializer;
private static final javax.xml.namespace.QName ns1_m_strFixedRevision_QNAME = new QName("", "
private static final javax.xml.namespace.QName ns1_m_dateFixedTimestamp_QNAME = new QName("",
private static final javax.xml.namespace.QName ns3_dateTime_TYPE_QNAME = SchemaConstants.QNAM
private CombinedSerializer ns3_myns3_dateTime__java_util_Calendar_DateTimeCalendar_Serializer
private static final javax.xml.namespace.QName ns1_m_strType_QNAME = new QName("", "mstrType"
private static final javax.xml.namespace.QName ns1_m_scriptOrder_QNAME = new QName("", "mscri
private static final javax.xml.namespace.QName ns1_m_strScriptState_QNAME = new QName("", "ms

After making the changes, the same section now looks like:

public class CSCCFileRecord_SOAPSerializer extends ObjectSerializerBase implements Initializable


private static final javax.xml.namespace.QName ns1_recordid_QNAME = new QName("", "recordid")
private static final javax.xml.namespace.QName ns3_long_TYPE_QNAME = SchemaConstants.QNAME_TY
private CombinedSerializer ns3_myns3__long__long_Long_Serializer;
private static final javax.xml.namespace.QName ns1_m_strFileName_QNAME = new QName("", "mstr
private static final javax.xml.namespace.QName ns3_string_TYPE_QNAME = SchemaConstants.QNAME_
private CombinedSerializer ns3_myns3_string__java_lang_String_String_Serializer;
private static final javax.xml.namespace.QName ns1_m_strFixedRevision_QNAME = new QName("", "
private static final javax.xml.namespace.QName ns1_m_dateFixedTimestamp_QNAME = new QName("",
private static final javax.xml.namespace.QName ns3_dateTime_TYPE_QNAME = SchemaConstants.QNAM
private CombinedSerializer ns3_myns3_dateTime__java_util_Calendar_DateTimeCalendar_Serializer
private static final javax.xml.namespace.QName ns1_m_strType_QNAME = new QName("", "mstrType
private static final javax.xml.namespace.QName ns1_m_scriptOrder_QNAME = new QName("", "mscr
private static final javax.xml.namespace.QName ns1_m_strScriptState_QNAME = new QName("", "m

Now you are ready to code!

Writing Code
Now the real fun begins, we are ready to actually start writing code.

Invoking a web service operation


NetBeans offers a really neat tool that can help you get started. You can call a web service operation and have
NetBeans place actual code in your java class. It is not complete code (it does not fill out paramters, for
example), but for your first time it can be of great help. Once you become more familiar with the TestTrack
SOAP interface you may find yourself using this less and less.

On the Main.java file, place your cursor under the "// TODO code application logic " comments, right click
Editing the classes

TestTrack_SOAP_SDK_Tutorial__NetBeans_Java_(JAXRPC)
and select Web Service Client Resources > Call Web Service Operation. The Select Operation to Invoke
dialog appears.

Figure 4 Select Operation to Invoke dialog


For this example, we'll select the getProjectList and click OK. The following code now appears in the
Main.java file:

try { // This code block invokes the Ttsoapcgi:getProjectList operation on web service
testtrack_Interface.Ttsoapcgi ttsoapcgi = new testtrack_Interface.Ttsoapcgi_Impl();
testtrack_Interface.TtsoapcgiPortType _ttsoapcgi = ttsoapcgi.getTtsoapcgi();
_ttsoapcgi.getProjectList(/* TODO enter operation arguments*/);
} catch(javax.xml.rpc.ServiceException ex) {
java.util.logging.Logger.getLogger(testtrack_Interface.Ttsoapcgi.class.getName()).log(jav
} catch(java.rmi.RemoteException ex) {
java.util.logging.Logger.getLogger(testtrack_Interface.Ttsoapcgi.class.getName()).log(jav
} catch(Exception ex) {
java.util.logging.Logger.getLogger(testtrack_Interface.Ttsoapcgi.class.getName()).log(jav
}

All you have to do now is fill out the parameters where the comments /* TODO enter operation arguments*/
appear. However, after you get the list of projects you may want to do something with them, so other code
may also be necsessary.

The following is the same piece of code but with the following additions:

Imports the testtrack_Interface package (to avoid having to prepend each object with the package name) and
removes 'testtrack_Interface' from object definintions.
Passes username and password to the getProjecList method.
Loops through each project and prints out each name.
package ttsoapsample;
import testtrack_Interface.*;
/**
*

Invoking a web service operation

TestTrack_SOAP_SDK_Tutorial__NetBeans_Java_(JAXRPC)
* @author cremerf
*/
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic
try
{ // This code block invokes the Ttsoapcgi:getProjectList operation on web service
Ttsoapcgi ttsoapcgi = new Ttsoapcgi_Impl();
TtsoapcgiPortType _ttsoapcgi = ttsoapcgi.getTtsoapcgi();
CProject[] projectList = _ttsoapcgi.getProjectList("Administrator","password");
for (int i =0; i < projectList.length;i++)
{
System.out.println(projectList[i].getDatabase().getName());

}
}
catch(javax.xml.rpc.ServiceException ex)
{
java.util.logging.Logger.getLogger(testtrack_Interface.Ttsoapcgi.class.getName()).log(
}
catch(java.rmi.RemoteException ex)
{
java.util.logging.Logger.getLogger(testtrack_Interface.Ttsoapcgi.class.getName()).log(
}
catch(Exception ex)
{
java.util.logging.Logger.getLogger(testtrack_Interface.Ttsoapcgi.class.getName()).log(
}

}
}

Setting the ttsoapcgi url


In the methods shown above the URL to the SOAP cgi is already set. The URL was obtained from the WSDL
file and the URL in the WSDL file was set during the installaion of the SOAP components.
To change the URL programatically, invoke the ttsoapcgi object and change the URL as follows:

//Define soap cgi object


TtsoapcgiPortType_Stub _ttsoapcgi = (TtsoapcgiPortType_Stub)(new Ttsoapcgi_Impl().getTtsoapcg
//Set the soap cgi URL
_ttsoapcgi._setProperty(javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY, "http://yourserver/ttso

Setting the ttsoapcgi url

10

TestTrack_SOAP_SDK_Tutorial__NetBeans_Java_(JAXRPC)

Sample Methods
The following are excerpts from a class created to handle all calls made to the web service.
The TtsoapcgiPortType object (_ttsoapcgi) is generated when the class is instantiated and therefore can be
reused each time the same instance of the _ttsoapcgi object is used.
NOTE: The following variables are declared as public and therefore are accessible to all of the methods:
ttCookie(long)
ttUsername(String)
ttPassword(String)
ttProjectName(String)
_ttsoapcgi(TtsoapcgiPortType)

Logging into a project


Logging into a project requires a CProject object. You can either get the list of projects and go through the
array until you find the one you want to log into, or you can create a CProject object from scratch.
The example above shows you how to loop through a CProject[] array already, so the method below shows
how to build a CProject object from scratch and then log in. If the process fails it returns false.
public boolean Login()
{
boolean result = false;
//First we need to build the project object
//Create the database object and set its name
CDatabase ttDatabase = new CDatabase();
ttDatabase.setName(ttProjectName);
//Create the project options object
CProjectDataOption[] ttProjOps = new CProjectDataOption[2];
//Allow TestTrack Pro access
ttProjOps[0].setName("TestTrack Pro");
//Allow TestTrack TCM access
ttProjOps[1].setName("TestTrack TCM");
//Now create the project object
CProject ttProj = new CProject();
ttProj.setDatabase(ttDatabase);
ttProj.setOptions(ttProjOps);
//Now we can try to log in
try
{ // This code block invokes the Ttsoapcgi:projectLogon operation on web service
ttCookie = _ttsoapcgi.projectLogon(ttProj, ttUsername, ttPassword);
if (ttCookie > 0)
{

Sample Methods

11

TestTrack_SOAP_SDK_Tutorial__NetBeans_Java_(JAXRPC)
result = true;
}
}

catch(Exception ex)
{
java.util.logging.Logger.getLogger(testtrack_Interface.Ttsoapcgi.class.getName()).lo
}
return result;
}

Getting a defect list array (CRecordListSoap)


This method can be used get a defects list. You must pass it a string array containing the columns to retrieve.
The column names are those that are displayed in the defect list window.

public CRecordListSoap getDefects(String[] m_ColList)


{
//We do not want to get every single column, so we first must build our CTableColumn[
//We initialize the size of the array to 3 since that is how many columns we are inte
CTableColumn[] m_Columns = new CTableColumn[m_ColList.length];
for (int i = 0; i < m_ColList.length; i++)
{
//We need to instantiate each column (you'll get a null exception if you don't)
m_Columns[i] = new CTableColumn();
//After you instantiate the column, then give it the name
m_Columns[i].setName(m_ColList[i]);
}
//Define our variable that will hold the defects
//I am defining it here because I will use it outside of the
//embedded try catch below
CRecordListSoap m_Records = new CRecordListSoap();
try
{

//Get defect table name


CDatabaseTable[] m_Tables = _ttsoapcgi.getTableList(ttCookie);
//Populate the crl variable
m_Records = _ttsoapcgi.getRecordListForTable(ttCookie, m_Tables[0].getName(), "",

}
catch (Exception fcc)
{
java.util.logging.Logger.getLogger(Ttsoapcgi.class.getName()).log(java.util.loggi
}
return m_Records;
}

Get defect for edit


public CDefect GetDefectForEdit(long defNum)
{

Logging into a project

12

TestTrack_SOAP_SDK_Tutorial__NetBeans_Java_(JAXRPC)

CDefect m_Defect = new CDefect();


try
{
m_Defect = _ttsoapcgi.editDefect(ttCookie,defNum,"",false);
}
catch(java.rmi.RemoteException ex)
{
java.util.logging.Logger.getLogger(Ttsoapcgi.class.getName()).log(java.util.logging.L
}
return m_Defect;
}

Save Defect

public boolean SaveDefect(CDefect m_Defect)


{
boolean result = false;
int s_result = 1;
try
{
s_result = _ttsoapcgi.saveDefect(ttCookie, m_Defect);
}
catch(java.rmi.RemoteException ex)
{
java.util.logging.Logger.getLogger(Ttsoapcgi.class.getName()).log(java.util.logging.L
}
if (s_result == 0)
{
result = true;
}
return result;
}

Download
I have posted below a project I created following the steps in this article. It includes everything, including the
.class files created by NetBeans. Note that this example does not employ the method that allows you to change
the URL prgramatically.
It does contain the .java and .class files created from the WSDL.
NetBeans Project

Get defect for edit

13

You might also like