Web Service Development Guide : PART II Client and Server Options : Chapter 8 Developing Services : Developing and Running the Example
Developing and Running the Example
If you have already generated code for this example based on the discussion in Chapter 7, you may skip to “Using the Server Implementation”.
Invoking the Generator
Make sure that you have set up your environment as described in Chapter 2, “Setup,” in the HydraExpress User Guide.
Change the current directory to the examples\webservices\DayOfWeek directory under the RWSF_HOME directory, as shown below:
Windows
cd %RWSF_HOME%\examples\webservices\DayOfWeek
UNIX/Linux
cd $RWSF_HOME/examples/webservices/DayOfWeek
In addition to the DayofWeek WSDL and the provided implementation files, this directory contains a HydraExpress project file, example-project.xml. This file provides custom configuration information to the generator. (For more information on the HydraExpress project file, see Chapter 21, “The Project File and Directory Structure.”
If you open this file, you’ll note that it identifies a value for the project-name attribute and a files element that references the DayofWeek.wsdl, so there is no need to include these items on the command line if this file is provided to the generator.
Run rwsfgen with example-project.xml as the sole argument, as follows:
 
prompt> rwsfgen example-project.xml
The above invocation is exactly the same as the following:
 
prompt> rwsfgen -projectname DayOfWeekExample -whitespace DayofWeek.wsdl
The two required options above are -projectname and the name of the file to parse.
NOTE >> If you are creating only a service, you may use the option -noclient to generate only server-side code.
HydraExpress generates server and client-side code, sample applications, configuration files, makefiles, MSVC project files, and documentation into a directory DayOfWeekExample, using the options included in the example-project.xml file.
Files are separated into several subdirectories according to type, as shown below.
 
DayOfWeekExample/
app/
client
server
bin
codegen/
client
server
conf
docs
include/
DayOfWeekExample
lib
This example is also used in Chapter 7 to discuss client code. See Table 4 for a list of generated files.
Using the Server Implementation
HydraExpress generates a set of classes and XML configuration files to implement the Web service. The C++ source files are generated into the app\server and codegen\server directories, and the header files into the include\DayOfWeekExample directory. Once the service is built, it is hosted by the Agent. (See Chapter 23, “Options for Deploying Services.”
To implement the server, you need be concerned only with the abstract base class for the server implementation and the sample implementation, which derives from the abstract base class. In this example, these classes are
DayOfWeekPortTypeBase
DayOfWeekPortTypeImp
To implement the server, either create a class that derives from the generated implementation base class, or implement the methods in the sample implementation. In most cases, modifying the sample implementation is the simplest approach.
This example ships with a server and a client implementation that you can use to quickly compile and run the example. These are discussed below.
The generated header file for the server implementation contains the signatures for the generated methods. Method names match the operation names specified in the WSDL file, with the first letter of the name converted to lower case. Parameter names match the part names in the WSDL with an underscore and the direction of the part appended to the name. For example, an in part named tickerSymbol will have the name tickerSymbol_in, while an inout part named targetStruct will have the name targetStruct_inout. For details on naming convention in the generated code, see Appendix A.
Although the class declaration for the implementation abstract base class may contain several functions, the derived implementation should override only the pure virtual functions, unless otherwise noted. The sample below shows the relevant declaration in the server implementation header file.
The Generated Abstract Base Class
The base class DayOfWeekPortTypeBase is located in the include\DayOfWeekExample directory. Following is an excerpt.
 
class DAYOFWEEKPORTTYPESERVICE_DECLSPEC
DayOfWeekPortTypeBase : public rwsf::MessageHandlerImp //1
{
public:
virtual ~DayOfWeekPortTypeBase();
 
virtual void init(const rwsf::Config& initParams); //2
virtual void destroy();
 
virtual std::string getDayOfWeek(rwsf::CallInfo& callInfo, //3
const std::string& date_in) = 0;
/**
* If the assertion fails, create and throw a rwsf::Exception
* exceptionwith the given fault string
**/
void serverAssert(bool assertion, const RWCString& msg) const; //4
 
};
 
//1 Inherits from rwsf::MessageHandlerImp.
//2 The virtual functions init() and destroy() may or may not be overridden.
//3 Pure virtual function representing the operation in the WSDL. The derived implementation must override this function to implement the GetDayOfWeek operation.
//4 If assertion is false, creates and throws a rwsf::ServerFault object with the fault string msg.
The Generated Sample Implementation
The generated sample implementation provides a simple implementation for the service.
The generated sample header, DayOfWeekPortTypeImp.h, shows the basic structure of a class derived from the server implementation base class. The code below shows the implementation declaration from the file:
 
#include "DayOfWeekExample/DayOfWeekPortTypeBase.h" //1
{
class DAYOFWEEKPORTTYPESERVICESAMPLE_DECLSPEC
DayOfWeekPortTypeImp : public DayOfWeekPortTypeBase //2
public:
virtual std::string getDayOfWeek(rwsf::CallInfo& callInfo, //3
const std::string& date_in);
};
//1 Includes the definition of the generated implementation base class, DayOfWeekPortTypeBase.
//2 Derives the concrete implementation class DayOfWeekPortTypeImp from the base class.
//3 Declares the getDayOfWeek method. Notice that this function handles the SOAP request as a C++ method call. The message handler parses the SOAP message received from the client to create the string provided to the getDayOfWeek method. The message handler translates the string that the method returns into a SOAP response.
The callInfo parameter is used for passing any additional information to the implementation, such as session data, SOAP headers, and transport headers. For information on HydraExpress’s support for advanced headers, see Chapter 15, “SOAP and Transport Headers.” To use the callInfo parameter for session support, see Chapter 18, “Sessions and State.”
Now let’s look at the generated sample implementation (named DayOfWeekPortTypeImp.cpp).
 
#include "DayOfWeekPortTypeImp.h" //1
 
RWSF_DEFINE_MESSAGE_HANDLER(DayOfWeekPortTypeImp) //2
 
std::string DayOfWeekPortTypeImp::getDayOfWeek(rwsf::CallInfo& callInfo,const
std::string& date_in)
{
typedef std::string returnType;
 
throw rwsf::ServerFault("Sorry: the service was invoked but the "
"requested operation \"getDayOfWeek\" has "
"not been implemented. An implementation "
"must be written."); //3
return returnType(); // (never executed) //4
}
 
//1 Includes the header for the derived implementation class.
//2 This macro registers your service and is correctly declared and implemented if you use the default name for the implementation class. See “Using a Different Implementation Name” for information on how to use a different name for the implementation class.
//3 Throws a rwsf::ServerFault notifying the client that the operation is not yet implemented.
//4 Returns a default-constructed std::string. Note that this line is unreachable. The sample includes this line for documentation purposes and to quiet compiler warnings.
The Provided Sample Implementation
To complete the service, we need to implement the method getDayofWeek() in the service implementation. For the purposes of this example, we will use the provided sample implementation DayOfWeekPortTypeImp.cpp rather than editing the above generated one. The provided implementation implements the getDayofWeek() method using class rwsf::DateTime which provides a method that returns the day of the week for any valid date.
Let’s look at the code. Here’s an excerpt from the provided implementation DayOfWeekPortTypeImp.cpp located in your <installdir>\examples\DayOfWeek directory.
 
std::string
DayOfWeekPortTypeImp::getDayOfWeek(rwsf::CallInfo& info,
const std::string& date_in)
{
std::string dateStr(date_in); //1
rwsf::DateTime dt(dateStr, rwsf::DateTime::setDate); // 2
// need to convert from DateTime to std::string to return to client
std::string weekDay = dt.weekDayName(); // 3
return weekDay;
}
 
//1 Copies the value string date_in containing the date provided by the client, to dateStr.
//2 Constructs an rwsf::DateTime instance dt and sets the date with the contents of dateStr.
//3 Method weekDayName() of rwsf::DateTime returns the name of the week for this date as a string, which is returned to the client.
Compiling the Service
HydraExpress creates makefiles for building the server and client code. To build the server from the command line using the makefiles, go to “Compiling Using the Makefile”.
If you are on Windows, you can also build the client and server code using the generated solution (MSVC) file, as described in “Compiling Using the Makefile”.
Before building this example, copy the provided sample files from the <installdir>\examples\webservices\DayofWeek to the new DayOfWeekExample directory, allowing the provided files to overwrite the generated files, as follows:
DayOfWeekPortClient.cpp
Copy to DayOfWeekExample\app\client
DayOfWeekPortTypeImp.cpp
Copy to DayOfWeekExample\app\server
NOTE >> Make sure that you have set up your environment as described in Chapter 2, “Setup,” in the HydraExpress User Guide and be sure you have set up your command window with the MSVC environment.
A Note on Deploying the Client Application
The generated makefile includes a deploy target to deploy the sample client. If you have compiled the client using MSVC on Windows, a deployment batch file is generated for your convenience. See “Deploying Services Compiled with MSVC”.
Compiling Using the Makefile
From a command prompt, change to the directory DayOfWeekExample, and simply run nmake (Windows) or make (UNIX or Linux) at the command prompt.
Using the project-level makefile builds all components created by the generator for this project according to the options used. For example, invoking the generator with the ‑noserver option creates a makefile that does not build server components.
NOTE >> If you wish to build just the client or server, the top-level makefile accepts a server or client target.
The makefile builds any components created when the generator created the makefile, placing them into top-level bin and lib directories as follows:
Windows
/bin
.exe, .dll
 
/lib
.lib
UNIX/Linux
/bin
.exe
 
/lib
.so
Compiling Using MSVC
On Windows, you can compile code through MSVC projects. Double-click on the solution to open it in MSVC, then build by selecting the appropriate item from the Build menu, or by right-clicking on the item you wish to build and selecting the appropriate item from the pop-up menu.
For more detailed information on building and compiling using MSVC, see the readme file located in the examples directory, <installdir>\examples\webservices\DayofWeek.
Deploying the Service
The generated makefile includes a deploy target to deploy the sample service. If you have compiled the service using MSVC on Windows, a deployment batch file is generated for your convenience. To load the service into the Agent, you must run the deploy target when the Agent is not running. The Agent must then be restarted for the deployment to take effect.
Deploying with the Makefile
To deploy the service, follow the steps in this section.
1. If the Agent is currently running, stop it by running the rwsfserver stop command as shown below:
Windows
rwsfserver stop
UNIX/Linux
rwsfserver stop
2. Run nmake (Windows) or make (UNIX or Linux) at the command prompt with the target deploy. The makefile deploys the service into the HydraExpress installation. The DLL or shared library for the service is placed in <installdir>\apps-bin on Windows and <installdir>/apps-lib on UNIX/Linux.
For example, the following command line builds the sample service library, deploys it as stated above, and copies the WSDL and configuration files for the service into the apps\servlets directory beneath the HydraExpress installation:
Windows
nmake deploy
UNIX/Linux
make deploy
3. Restart the Agent to load the new service. To restart the Agent, run the rwsfserver start as shown below:
Windows
rwsfserver start
UNIX/Linux
rwsfserver start
Deploying Services Compiled with MSVC
If you compiled the Web service with an MSVC project file on Windows platforms, deploy the servlet as follows:
1. Stop the Agent, if necessary, as described in the previous section.
2. Run the deployment batch file generated in the top level code generation directory as a convenience: deployDebug.bat (for debug builds) or deployRelease.bat (for release builds).
3. Start the Agent as described in the previous section.
Testing the Service
NOTE >> HydraExpress’s generated client sample implementations all point to the project-directory\conf directory to locate the client configuration files. If you move the client executable without maintaining the same code generation directory structure, or you invoke the client from another location, be aware that you must edit the client implementation to maintain the correct path to the conf directory.
To test the service, just invoke the client from the DayofWeekExample\bin directory:
 
prompt> DayOfWeekPortClient
The sample below shows output from a client that uses the implementation above:
 
Enter date: 6/21/2003
06/21/03 was a Saturday
 
NOTE >> While you may enter either a two-digit year or a four-digit year into the DayofWeek service, entering a four-digit year will ensure that the date returned to you is for the century you intend. For example, a year of “02” will be read as “1902.”