Welcome to Axis C++, the opensource c++ implementation of SOAP ! What is
SOAP? SOAP is an XML-based communication protocol and encoding format for
inter-application communication. Originally conceived by Microsoft and Userland
software, it has evolved through several generations and the current spec, SOAP
1.2 is fast growing in popularity and usage. The W3C's XML Protocol working
group is in the process of turning SOAP into a true open standard, and as of
this writing has released a working draft of SOAP 1.2, which cleans up some of
the more confusing areas of the 1.1 spec. SOAP is widely viewed as the backbone
to a new generation of cross-platform cross-language distributed computing
applications, termed Web Services. What is Axis C++? Axis C++ is essentially a
SOAP engine.
This version is written in C++. Axis C++ SOAP engine adopts
most of Axis Java architecture. But it has some major architectural innovations
over Axis Java in order to achieve greater performance and efficiency.
- Soap
engine with both client and server support
- Partial
support for both SOAP 1.1 and SOAP 1.2
- WSDD
based deployment with dynamic deployment tools.
- Support
for all basic types, Complex types and Arrays
- WSDL2WS
tool for building C/C++ components
- Server
side – Skeletons and Wrappers
- Client
side – Stubs
- WSDL2WS
tool that generates wrappers, which perform the following functions. These
wrappers act as RPC
Providers.
-
Serialization
-
Deserialization
- Method
invocation
- WSDLs
hosted statistically in the server.
-
Standalone server (with HTTP support)
- Web
server modules for Apache 1.3 & (Linux/Windows)
- Basic
Wrapper Class Generator tool with following functionalities.
-
Wrapping existing systems as web services
- WSDL
generation
- Web
interface to the deployed services and their WSDL s.
- Sample
web services and client applications.
- Speed: Axis uses SAX (event-based) parsing to acheive significantly greater
speed than earlier versions of Apache
SOAP.
-
Flexibility
-
Stability , Component oriented Deployment
-
Transport Framework
- WSDL
support
AxisC++ 1.0supports the Web Service Description Language, version 1.1, which allows you to easily build stubs to access remote services, and also to automatically export machine-readable descriptions of your deployed services from Axis. We hope you enjoy using Axis c++ 1.0. Please note that this is an open-source effort - if you feel the code could use some new features or fixes, please get involved and lend a hand! The Axis developer community welcomes your participation. Let us know what you think! Please send feedback about the package to mailto:axis-user@xml.apache.org
Full SOAP 1.2 support.
See the Axis Installation Guide for instructions on installing Axis C++
Before running the examples in this guide, you'll need to make sure that your
environment variables and other configurations are set correctly as described in
Installation guide. That is you need
-
Axis C++
- Apache1.3
-
xerces-C
- j2SDK1.4
installed and configured.
Let's take a look at a sample InteropBase service client that will call methods of a
InteropBase service deployed on Axis C++. You can
find the InteropBase.wsdl for this example at
$AXISCPP_HOME/src/server/samples/interoptests/base
When starting with the valid WSDL file to use Axis C++ you have to get
started with the tool called WSDL2Ws which is written in Java. source for
WSDL2Ws tool is in
$axiscpp_home/src/wsdl
You need the following jar files included in the CLASSPATH .
- axis.jar
-
commons-discovery.jar
-
commons-logging.jar
-
jaxrpc.jar
-
saaj.jar
- wsdl4j.jar
- xml-apis.jar
The CLASSPATH Environment Variable should have the
absolute paths of the jars (including the jar file name) given as a colon
separated list
Here is a sample /home/axisuser/.bash_profile file where we specified those
AXIS_JARS_HOME="$AXISCPP_HOME/lib/axisjava"
AXIS_JARS="$AXIS_JARS_HOME/axis-
ant.jar:$AXIS_JARS_HOME/axis.jar:$AXIS_JARS_HOME/commons-
discovery.jar:$AXIS_JARS_HOME/commons-
logging.jar:$AXIS_JARS_HOME/jaxrpc.jar:$AXIS_JARS_HOME/log4j-
1.2.4.jar:$AXIS_JARS_HOME/saaj.jar:$AXIS_JARS_HOME/wsdl4j.jar"
JAVA_HOME="/usr/java"
PATH="$PATH:$JAVA_HOME/bin:."
CLASSPATH="$CLASSPATH:./:$JAVA_HOME/lib:$AXIS_JARS:"
export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC AXIS_JARS_HOME
AXIS_JARS JAVA_HOME CLASSPATH
Now
$ cd $AXISCPP_HOME/c/src/wsdl/
$ mkdir temp
$javac -d ./temp -sourcepath . ./org/apache/axis/wsdl/wsdl2ws/*.java
$cd temp
$jar -cvf wsdl2ws.jar org
$cp -f wsdl2ws.jar $AXISCPP_HOME/lib/axis
add this jar to the classpath as well.
We use the sample at
$AXISCPP_HOME/src/server/samples/interoptests/base.
We use this sample to demonstrate the generation of serverside skeletons and how to deploy
a web service using it.
Inside this folder you will find InteropBase.wsdl file using which we generate skeleton and Wrappers. Here is the command line arguments to generate the skeleton.
cd $AXISCPP_HOME/server/samples/interoptests/base
% java org.apache.axis.wsdl.wsdl2ws.WSDL2Ws InteropBase.wsdl -lc++ -sserver
Note: If you give -o. /GenClassesServer then the server create a folder named GenClassServer and put the source there. Otherwise the source is put in the current folder where the tool is run.
In this sample it generates
-
ArrayOffloat.h
-
ArrayOfint.h
-
ArrayOfSOAPStruct.h
-
ArrayOfstring.h
-
InteropTestPortType.h
-
InteropTestPortTypeWrapper.h
-
SOAPStruct.h
-
InteropTestPortType.cpp
-
InteropTestPortTypeService.cpp
-
InteropTestPortTypeWrapper.cpp
-
SOAPStruct.cpp
You can fill skeltons with your business logic. In this
example it is done for you in InteropTestPortType.Cpp
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//This is
the Service implementation CPP file genarated by theWSDL2Ws.
//
InteropTestPortType.cpp: implemtation for the InteropTestPortType.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include
"InteropTestPortType.h"
InteropTestPortType::InteropTestPortType()
{
}
InteropTestPortType::~InteropTestPortType()
{
}
string
InteropTestPortType::echoString(string Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
ArrayOfstring
InteropTestPortType::echoStringArray(ArrayOfstring Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
int
InteropTestPortType::echoInteger(int Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
}
ArrayOfint
InteropTestPortType::echoIntegerArray(ArrayOfint Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
float
InteropTestPortType::echoFloat(float Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
ArrayOffloat
InteropTestPortType::echoFloatArray(ArrayOffloat Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
SOAPStruct*
InteropTestPortType::echoStruct(SOAPStruct* Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
ArrayOfSOAPStruct
InteropTestPortType::echoStructArray(ArrayOfSOAPStruct Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
void
InteropTestPortType::echoVoid()
{
}
Axis_Base64Binary
InteropTestPortType::echoBase64(Axis_Base64Binary Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
Axis_DateTime
InteropTestPortType::echoDate(Axis_DateTime Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
Axis_HexBinary
InteropTestPortType::echoHexBinary(Axis_HexBinary Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
Axis_Decimal
InteropTestPortType::echoDecimal(Axis_Decimal Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
Axis_Boolean
InteropTestPortType::echoBoolean(Axis_Boolean Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
The Folder called deploy in the /home/axisuser/projects/axis_c/ should be copied to apache root folder .Rename the deploy folder as "Axis". Give all permissions to this folder.
$ cp
–rf /home/axisuser/projects/axis_c/deloy /usr/local/apache
$ cd /usr/local/apache
$ mv deploy Axis
$ chmod -R 777 Axis
Now set the environment variable AXIS_HOME pointing to this directory.
AXIS_HOME="/usr/local/apache/Axis"
Type the Following Command to build the service(You can always use makefiles
instead of the following commands to build.)
cd $AXISCPP_HOME/src/server/samples/introptests/base
By typing this in the command line the dynamic library ( libinteropbase.so
for example) is created which is used for the deployment. This library is
automatically is placed in
$AXIS_HOME/webservices where $AXIS_HOME = /usr/local/apache/Axis
Modify the server.wsdd. Modify the server.wsdd appropriate for your service. (You have a sample server.wsdd file given below appropriately filled for this service).
<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:C="http://xml.apache.org/axis/wsdd/providers/c">
<globalConfiguration>
< service name="InteropBase" provider="C:RPC" description="SOAPBuilders Interoperability Lab Round 2 base test suite described at http://www.whitemesa.com/interop/proposal2.html ">
< parameter name="allowedMethods" value="echoString EchoInt echoStringArray echoInteger echoIntegerArray echoFloat echoFloatArray echoStruct echoStructArray echoVoid echoBase64 echoDate echoHexBinary echoDecimal echoBoolean "/>
< parameter name="className" value="/usr/local/apache/Axis/webservices/libinteropbase.so"/>
< /service>
</deployment>
Note: You should make a backup of $AXIS_HOME/conf/server.wsdd and edit the original file so that it is exactly as above.
server.wsdd should be in
/usr/local/apache/Axis/conf/
Start the Apache server
$ /usr/local/apache/bin/apachectl start
Now open a browser and
enter the link http://localhost:80/axis If the service is correctly deployed
then it will be displayed in a table of deployed services which contain
information such as service name, link to wsdl and a description of the service.
WSDL2Ws tools will generate the stubs for the client side. You will have C++
Client class and header file.
cd $AXISCPP_HOME/src/client/samples/interoptests/base
$ java org.apache.axis.wsdl.wsdl2ws.WSDL2Ws InteropBase.wsdl -lc++ -sclient
Note: again if you specify -o./GenClassesClient you will have source generated inside GenClassClient folder instead of current folder where the tool is run. Before compiling the client you have to write a class which contain a main method in which InteropTestPortType instance is created and its methods are called.
//
InteropBaseClient.cpp : Defines the entry point for the console application.
//
#include
"InteropTestPortType.h"
#define
ARRAYSIZE 2
int
main(int argc, char* argv[])
{
int x;
char
buffer[100];
InteropTestPortType ws;
printf("invoking echoString...\n");
//testing
echoString
if
(ws.echoString("hello world") == "hello world")
printf("successful\n");
else
printf("failed\n");
//
testing echoStringArray
ArrayOfstring arrstr;
arrstr.m_Array = new string[ARRAYSIZE];
arrstr.m_Size = ARRAYSIZE;
for
(x=0;x
sprintf(buffer, "%dth element of string array", x);
arrstr.m_Array[x] = buffer;
}
printf("invoking echoStringArray...\n");
if
(ws.echoStringArray(arrstr).m_Array != NULL)
printf("successful\n");
else
printf("failed\n");
//
testing echoInteger
printf("invoking echoInteger...\n");
if
(ws.echoInteger(56) == 56)
printf("successful\n");
else
printf("failed\n");
//
testing echoIntegerArray
ArrayOfint arrint;
arrint.m_Array = new int[ARRAYSIZE];
arrint.m_Size = ARRAYSIZE;
for
(x=0;x
arrint.m_Array[x] = x;
}
printf("invoking echoIntegerArray...\n");
if
(ws.echoIntegerArray(arrint).m_Array != NULL)
printf("successful\n");
else
printf("failed\n");
//
testing echoFloat
printf("invoking echoFloat...\n");
if
(ws.echoFloat(1.4214) > 1.42)
printf("successful\n");
else
printf("failed\n");
//
testing echoFloat
ArrayOffloat arrfloat;
arrfloat.m_Array = new float[ARRAYSIZE];
arrfloat.m_Size = ARRAYSIZE;
for
(x=0;x
arrfloat.m_Array[x] = 1.1111*x;
}
printf("invoking echoFloatArray...\n");
if
(ws.echoFloatArray(arrfloat).m_Array != NULL)
printf("successful\n");
else
printf("failed\n");
//
testing echo Struct
SOAPStruct stct;
stct.varFloat = 12345.7346345;
stct.varInt = 5000;
stct.varString = "This is string in SOAPStruct";
printf("invoking echoStruct...\n");
if
(ws.echoStruct(&stct) != NULL)
printf("successful\n");
else
printf("failed\n");
//testing
echo Array of Struct
ArrayOfSOAPStruct arrstct;
arrstct.m_Array = new SOAPStruct[ARRAYSIZE];
arrstct.m_Size = ARRAYSIZE;
for
(x=0;x
arrstct.m_Array[x].varFloat = 1.1111*x;
arrstct.m_Array[x].varInt = x;
sprintf(buffer, "varString of %dth element of SOAPStruct array", x);
arrstct.m_Array[x].varString = buffer;
}
//testing
echo Struct Array
printf("invoking echoStructArray...\n");
if
(ws.echoStructArray(arrstct).m_Array != NULL)
printf("successful\n");
else
printf("failed\n");
//testing
echo void
printf("invoking echoVoid...\n");
ws.echoVoid();
printf("successful\n");
//testing
echo base 64 binary
printf("invoking echoBase64...\n");
if
(ws.echoBase64("
BCDF675E234242WHRTKMJDGKGUEJ898636JFJFHEJDGWTDHFJRURYGBCDHTWRSG")
=="BCDF675E234242WHRTKMJDGKGUEJ898636JFJFHEJDGWTDHFJRURYGBCDHTWRSG")
printf("successful\n");
else
printf("failed\n");
time_t
tim;
time(&tim);
tm* lt =
gmtime(&tim);
printf("invoking echoDate...\n");
if
(memcmp(&ws.echoDate(*lt), lt, sizeof(tm)) == 0)
printf("successful\n");
else
printf("failed\n");
//testing
echo hex binary
printf("invoking echoHexBinary...\n");
if
(ws.echoHexBinary("CCCFFA46552BC7D5A09BC5F23DE9E0FE7862AD45BC87D02FEE") ==
"CCCFFA46552BC7D5A09BC5F23DE9E0FE7862AD45BC87D02FEE")
printf("successful\n");
else
printf("failed\n");
//testing
echo decimal
printf("invoking echoDecimal...\n");
if
(ws.echoDecimal(1234.567890) > 1234.56)
printf("successful\n");
else
printf("failed\n");
//testing
echo boolean
printf("invoking echoBoolean...\n");
if
(ws.echoBoolean(1) == 1)
printf("successful\n");
else
printf("failed\n");
getchar();
return 0;
}
Copy from $AXISCPP_HOME/bin/libaxiscpp_mod.a to $AXISCPP_HOME/lib/axis
Creating the client library
cd $AXISCPP_HOME/src/client
$sh autogen.sh
$sh runconfig
$make
$make install
This will automatically create libaxiscpp_client.so and copy it to the $AXISCPP_HOME/lib/axis (as configured in runconfig script)
Now
cd $AXISCPP_HOME/src/client/samples/interoptests/base
$ g++
-DHAVE_CONFIG_H -I. -I. -I.. -I$AXISCPP_HOME/include -Wshadow -Wall -pedantic
- ansi -g -O2 -c ./*.cpp -fPIC
$ g++ -g -O2 -o interopbase InteropBaseClient.o SOAPStruct.o InteropTestPortType.o
$AXISCPP_HOME/lib/axis/libaxiscpp_client.a $AXISCPP_HOME/lib/axis/libaxiscpp_mod.a -
L$AXISCPP_HOME/lib/xerces-c -lxerces-c -ldl
$AXISCPP_HOME/src/client/lib/libaxiscpp_client.a
$AXISCPP_HOME/release/libaxiscpp_mod.a -L$AXISCPP_HOME/lib/xerces-c -lxerces-c
-ldl
Start the Apache Server(Assuming base service is
deployed.)
$ /usr/local/apache/bin/apachectl start
to run
$ ./interopbase
If you want to test handlers go into the $AXISCPP_HOME/src/server/handlers folder where example handlers are included (If you use the binary download sample handler libraries are included in $(AXIS_HOME)/handlers folder(assuming that you created this folder as described in installation guide). Several sample handlers are included there covering the concepts of service specific, global and transport handlers. We will show you the detail of running a service specific handler named loghandler. The task of this handler is writing to a file the number of times the service is accessed.
cd
/home/axisuser/projects/axis_c/src/server/handlers/custom/loghandler
$sh autogen.sh
$sh runconfig
$make
$make install
The handler library will be installed at $(AXIS_HOME)/handlers/custom/loghandler Now edit the $(AXIS_HOME)/conf/server.wsdd to include the handler for a particular service.
<service name="InteropBase" provider="C:RPC" description="SOAPBuilders Interoperability Lab Round
2 base test suite described at http://www.whitemesa.com/interop/proposal2.html ">
<requestFlow name="calchandlers">
<handler name="LogAccessCount"
type="/usr/local/apache/Axis/handlers/custom/loghandler/libloghandler.so">
<parameter name="logAccessCountFile"
value="/usr/local/apache/Axis/handlers/custom/loghandler/LogAccessCountFile"/>
</handler>
</requestFlow>
<parameter name="allowedMethods" value="echoString EchoInt echoStringArray
echoInteger echoIntegerArray echoFloat echoFloatArray echoStruct echoStructArray echoVoid
echoBase64 echoDate echoHexBinary echoDecimal echoBoolean "/>
<parameter name="className" value="/usr/local/apache/Axis/webservices/libinteropbase.so"/>
</service>
Restart the apache web server and test your handler using the web service client for InteropBase webservice. When the client is run an entry will be added to /usr/local/apache/Axis/handlers/custom/loghandler/LogAccessCountFile Note that the folder in which the LogAccessCountFile is created should have write access. You can test the global handlers and transport handlers in a similar manner. Note the change you have to make in server.wsdd. You can see how this is done in the specimen folder $AXISCPP_HOME/deploy/conf/server.wsdd.
///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////Let's take a look at a sample InteropBase service client that will call methods of a
InteropBase service deployed on Axis C++. You can
find the InteropBase.wsdl for this example at
$AXISCPP_HOME/deploy/wsdls
You need the following jar files included in the CLASSPATH .
- axis.jar
-
commons-discovery.jar
-
commons-logging.jar
-
jaxrpc.jar
-
saaj.jar
- wsdl4j.jar
- xml-apis.jar
The CLASSPATH Environment Variable should have the
absolute paths of the jars (including the jar file name) given as a colon
separated list
Here is a sample /home/axisuser/.bash_profile file where we specified those
AXIS_JARS_HOME="$AXISCPP_HOME/lib/axisjava"
AXIS_JARS="$AXIS_JARS_HOME/axis-
ant.jar:$AXIS_JARS_HOME/axis.jar:$AXIS_JARS_HOME/commons-
discovery.jar:$AXIS_JARS_HOME/commons-
logging.jar:$AXIS_JARS_HOME/jaxrpc.jar:$AXIS_JARS_HOME/log4j-
1.2.4.jar:$AXIS_JARS_HOME/saaj.jar:$AXIS_JARS_HOME/wsdl4j.jar"
JAVA_HOME="/usr/java"
PATH="$PATH:$JAVA_HOME/bin:."
  CLASSPATH="$CLASSPATH:./:$JAVA_HOME/lib:$AXIS_JARS:$AXISCPP_HOME/lib/axis/wsdl2ws.jar"
export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC AXIS_JARS_HOME
AXIS_JARS JAVA_HOME CLASSPATH
We use the sample at
$AXISCPP_HOME/samples/interoptests/base.
We use this sample to demonstrate the generation of serverside skeletons and how to deploy
a web service using it.
Inside this folder you will find InteropBase.wsdl file using which we generate skeleton and Wrappers. Here is the command line arguments to generate the skeleton.
cd
$AXISCPP_HOME/samples/server/interoptests/base
% java org.apache.axis.wsdl.wsdl2ws.WSDL2Ws InteropBase.wsdl -lc++ -sserver
Note: If you give -o. /GenClassesServer then the server create a folder named GenClassServer and put the source there. Otherwise the source is put in the current folder where the tool is run.
In this sample it generates
-
ArrayOffloat.h
-
ArrayOfint.h
-
ArrayOfSOAPStruct.h
-
ArrayOfstring.h
-
InteropTestPortType.h
-
InteropTestPortTypeWrapper.h
-
SOAPStruct.h
-
InteropTestPortType.cpp
-
InteropTestPortTypeService.cpp
-
InteropTestPortTypeWrapper.cpp
-
SOAPStruct.cpp
You can fill skeltons with your business logic. In this
example it is done for you in InteropTestPortType.Cpp
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//This is
the Service implementation CPP file genarated by theWSDL2Ws.
//
InteropTestPortType.cpp: implemtation for the InteropTestPortType.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include
"InteropTestPortType.h"
InteropTestPortType::InteropTestPortType()
{
}
InteropTestPortType::~InteropTestPortType()
{
}
string
InteropTestPortType::echoString(string Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
ArrayOfstring
InteropTestPortType::echoStringArray(ArrayOfstring Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
int
InteropTestPortType::echoInteger(int Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
}
ArrayOfint
InteropTestPortType::echoIntegerArray(ArrayOfint Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
float
InteropTestPortType::echoFloat(float Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
ArrayOffloat
InteropTestPortType::echoFloatArray(ArrayOffloat Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
SOAPStruct*
InteropTestPortType::echoStruct(SOAPStruct* Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
ArrayOfSOAPStruct
InteropTestPortType::echoStructArray(ArrayOfSOAPStruct Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
void
InteropTestPortType::echoVoid()
{
}
Axis_Base64Binary
InteropTestPortType::echoBase64(Axis_Base64Binary Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
Axis_DateTime
InteropTestPortType::echoDate(Axis_DateTime Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
Axis_HexBinary
InteropTestPortType::echoHexBinary(Axis_HexBinary Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
Axis_Decimal
InteropTestPortType::echoDecimal(Axis_Decimal Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
Axis_Boolean
InteropTestPortType::echoBoolean(Axis_Boolean Value0)
{
//Following line is not generated. You have to fill it. Here it is filled for
you.
return Value0;
}
The Folder called deploy in the /home/axisuser/projects/axis_c/ should be copied to apache root folder .Rename the deploy folder as "Axis". Give all permissions to this folder.
$ cp
–rf /home/axisuser/projects/axis_c/deloy /usr/local/apache
$ cd /usr/local/apache
$ mv deploy Axis
$ chmod -R 777 Axis
Now set the environment variable AXIS_HOME pointing to this directory.
AXIS_HOME="/usr/local/apache/Axis"
Type the Following Command to build the service(You can always use makefiles
instead of the following commands to build.)
cd $AXISCPP_HOME/src/server/samples/introptest/base
By typing this in the command line the dynamic library ( libinteropbase.so
for example) is created which is used for the deployment. This library is
automatically is placed in
$AXIS_HOME/webservices where $AXIS_HOME = /usr/local/apache/Axis
Modify the server.wsdd. Modify the server.wsdd appropriate for your service. (You have a sample server.wsdd file given below appropriately filled for this service).
<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:C="http://xml.apache.org/axis/wsdd/providers/c">
<globalConfiguration>
< service name="InteropBase" provider="C:RPC" description="SOAPBuilders Interoperability Lab Round 2 base test suite described at http://www.whitemesa.com/interop/proposal2.html ">
< parameter name="allowedMethods" value="echoString EchoInt echoStringArray echoInteger echoIntegerArray echoFloat echoFloatArray echoStruct echoStructArray echoVoid echoBase64 echoDate echoHexBinary echoDecimal echoBoolean "/>
< parameter name="className" value="/usr/local/apache/Axis/webservices/libinteropbase.so"/>
< /service>
</deployment>
Note: You should make a backup of $AXIS_HOME/conf/server.wsdd and edit the original file so that it is exactly as above.
server.wsdd should be in
usr/local/apache/Axis/conf/
Start the Apache server
$ usr/local/apache/bin/apachectl start
Now open a browser and
enter the link http://localhost:80/axis If the service is correctly deployed
then it will be displayed in a table of deployed services which contain
information such as service name, link to wsdl and a description of the service.
WSDL2Ws tools will generate the stubs for the client side. You will have C++
Client class and header file.
cd $AXISCPP_HOME/samples/client/interoptests/base
$ java org.apache.axis.wsdl.wsdl2ws.WSDL2Ws InteropBase.wsdl -lc++ -sclient
Note: again if you specify -o./GenClassesClient you will have source generated inside GenClassClient folder instead of current folder where the tool is run. Before compiling the client you have to write a class which contain a main method in which InteropTestPortType instance is created and its methods are called.
//
InteropBaseClient.cpp : Defines the entry point for the console application.
//
#include
"InteropTestPortType.h"
#define
ARRAYSIZE 2
int
main(int argc, char* argv[])
{
int x;
char
buffer[100];
InteropTestPortType ws;
printf("invoking echoString...\n");
//testing
echoString
if
(ws.echoString("hello world") == "hello world")
printf("successful\n");
else
printf("failed\n");
//
testing echoStringArray
ArrayOfstring arrstr;
arrstr.m_Array = new string[ARRAYSIZE];
arrstr.m_Size = ARRAYSIZE;
for
(x=0;x
sprintf(buffer, "%dth element of string array", x);
arrstr.m_Array[x] = buffer;
}
printf("invoking echoStringArray...\n");
if
(ws.echoStringArray(arrstr).m_Array != NULL)
printf("successful\n");
else
printf("failed\n");
//
testing echoInteger
printf("invoking echoInteger...\n");
if
(ws.echoInteger(56) == 56)
printf("successful\n");
else
printf("failed\n");
//
testing echoIntegerArray
ArrayOfint arrint;
arrint.m_Array = new int[ARRAYSIZE];
arrint.m_Size = ARRAYSIZE;
for
(x=0;x
arrint.m_Array[x] = x;
}
printf("invoking echoIntegerArray...\n");
if
(ws.echoIntegerArray(arrint).m_Array != NULL)
printf("successful\n");
else
printf("failed\n");
//
testing echoFloat
printf("invoking echoFloat...\n");
if
(ws.echoFloat(1.4214) > 1.42)
printf("successful\n");
else
printf("failed\n");
//
testing echoFloat
ArrayOffloat arrfloat;
arrfloat.m_Array = new float[ARRAYSIZE];
arrfloat.m_Size = ARRAYSIZE;
for
(x=0;x
arrfloat.m_Array[x] = 1.1111*x;
}
printf("invoking echoFloatArray...\n");
if
(ws.echoFloatArray(arrfloat).m_Array != NULL)
printf("successful\n");
else
printf("failed\n");
//
testing echo Struct
SOAPStruct stct;
stct.varFloat = 12345.7346345;
stct.varInt = 5000;
stct.varString = "This is string in SOAPStruct";
printf("invoking echoStruct...\n");
if
(ws.echoStruct(&stct) != NULL)
printf("successful\n");
else
printf("failed\n");
//testing
echo Array of Struct
ArrayOfSOAPStruct arrstct;
arrstct.m_Array = new SOAPStruct[ARRAYSIZE];
arrstct.m_Size = ARRAYSIZE;
for
(x=0;x
arrstct.m_Array[x].varFloat = 1.1111*x;
arrstct.m_Array[x].varInt = x;
sprintf(buffer, "varString of %dth element of SOAPStruct array", x);
arrstct.m_Array[x].varString = buffer;
}
//testing
echo Struct Array
printf("invoking echoStructArray...\n");
if
(ws.echoStructArray(arrstct).m_Array != NULL)
printf("successful\n");
else
printf("failed\n");
//testing
echo void
printf("invoking echoVoid...\n");
ws.echoVoid();
printf("successful\n");
//testing
echo base 64 binary
printf("invoking echoBase64...\n");
if
(ws.echoBase64("
BCDF675E234242WHRTKMJDGKGUEJ898636JFJFHEJDGWTDHFJRURYGBCDHTWRSG")
=="BCDF675E234242WHRTKMJDGKGUEJ898636JFJFHEJDGWTDHFJRURYGBCDHTWRSG")
printf("successful\n");
else
printf("failed\n");
time_t
tim;
time(&tim);
tm* lt =
gmtime(&tim);
printf("invoking echoDate...\n");
if
(memcmp(&ws.echoDate(*lt), lt, sizeof(tm)) == 0)
printf("successful\n");
else
printf("failed\n");
//testing
echo hex binary
printf("invoking echoHexBinary...\n");
if
(ws.echoHexBinary("CCCFFA46552BC7D5A09BC5F23DE9E0FE7862AD45BC87D02FEE") ==
"CCCFFA46552BC7D5A09BC5F23DE9E0FE7862AD45BC87D02FEE")
printf("successful\n");
else
printf("failed\n");
//testing
echo decimal
printf("invoking echoDecimal...\n");
if
(ws.echoDecimal(1234.567890) > 1234.56)
printf("successful\n");
else
printf("failed\n");
//testing
echo boolean
printf("invoking echoBoolean...\n");
if
(ws.echoBoolean(1) == 1)
printf("successful\n");
else
printf("failed\n");
getchar();
return 0;
}
You will find the client libraries required to run the sample client installed in $AXISCPP_HOME/lib/axis
Now
cd $AXISCPP_HOME/samples/client/interoptests/base
$ g++
-DHAVE_CONFIG_H -I. -I. -I.. -I$AXISCPP_HOME/include -Wshadow -Wall -pedantic
- ansi -g -O2 -c ./*.cpp -fPIC
$ g++ -g -O2 -o interopbase InteropBaseClient.o SOAPStruct.o InteropTestPortType.o
$AXISCPP_HOME/lib/axis/libaxiscpp_client.a $AXISCPP_HOME/lib/axis/libaxiscpp_mod.a -
L$AXISCPP_HOME/lib/xerces-c -lxerces-c -ldl
$AXISCPP_HOME/src/client/lib/libaxiscpp_client.a
$AXISCPP_HOME/release/libaxiscpp_mod.a -L$AXISCPP_HOME/lib/xerces-c -lxerces-c
-ldl
Start the Apache Server(Assuming base service is deployed.)
$ /usr/local/apache/bin/apachectl start
To Run
$ ./interopbase
Sample handler libraries are included in $(AXIS_HOME)/handlers folder(assuming that you created this folder as described in installation guide). Several sample handlers are included there covering the concepts of service specific, global and transport handlers. We will show you the detail of running a service specific handler named loghandler. The task of this handler is writing to a file the number of times the service is accessed.
cp -rf $AXISCPP_HOME/deploy/handlers $(AXIS_HOME)/
<service name="InteropBase" provider="C:RPC" description="SOAPBuilders Interoperability Lab Round
2 base test suite described at http://www.whitemesa.com/interop/proposal2.html ">
<requestFlow name="calchandlers">
<handler name="LogAccessCount"
type="/usr/local/apache/Axis/handlers/custom/loghandler/libloghandler.so">
<parameter name="logAccessCountFile"
value="/usr/local/apache/Axis/handlers/custom/loghandler/LogAccessCountFile"/>
</handler>
</requestFlow>
<parameter name="allowedMethods" value="echoString EchoInt echoStringArray
echoInteger echoIntegerArray echoFloat echoFloatArray echoStruct echoStructArray echoVoid
echoBase64 echoDate echoHexBinary echoDecimal echoBoolean "/>
<parameter name="className" value="/usr/local/apache/Axis/webservices/libinteropbase.so"/>
</service>
Restart the apache web server and test your handler using the web service client for InteropBase webservice. When the client is run an entry will be added to /usr/local/apache/Axis/handlers/custom/loghandler/LogAccessCountFile Note that the folder in which the LogAccessCountFile is created should have write access. You can test the global handlers and transport handlers in a similar manner. Note the change you have to make in server.wsdd. You can see how this is done in the specimen folder $(AXISCPP_HOME)/deploy/conf/server.wsdd.
TODO: document how the users can write their own handlers and webservices. For
the time being users can refer to the samples given and follow their example
to write their own handlers and webservices. This task is fairly easy
if you follow the examples.
You can use the tcpmon program of Axis Java to view what goes on the wire when
a soap transaction is taking place. Please visit http://ws.apache.org/axis/ and get Axis java, to obtain tcpmon.
Your contribution to Axis C++ as a developer, tester is highly appreciated.
You can download the
latest source from the cvs repository as documented below.
Visit http://ws.apache.org/ click on “axis” and then on “CVS Repository” to find details on accessing the CVS Repository. It will have instructions similar to the following.
“Anyone can checkout source code from our anonymous CVS server. To do so, simply use the following commands (if you are using a GUI CVS client, configure it appropriately):
cvs -d :pserver:anoncvs@cvs.apache.org:/home/cvspublic login
password: anoncvs
cvs -d :pserver:anoncvs@cvs.apache.org:/home/cvspublic checkout ws-axis”
The examples given below will be based on these lines of instructions.
To use the command line cvs client go to http://www.cvshome.org and download the cvs binaries for windows. Extract the cvs binaries from the downloaded zip file. There will be a “cvs.exe” file when this is extracted. Set the PATH environment variable to where “cvs.exe” is. You would have to do the following to get a checkout from the command line cvs client.
cvs -d :pserver:anoncvs@cvs.apache.org:/home/cvspublic login
Now you will be prompted for the password. Enter the password.
password: anoncvs
Now enter the following cvs command to checkout the axis Repository.
cvs -d :pserver:anoncvs@cvs.apache.org:/home/cvspublic checkout ws-axis
The checkout of the repository will be created in the current directory in a folder named “ws-axis”