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
};
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);
};
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
}
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;
}
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.”