This document covers the following topics:
As a general rule, before using the EntireX RPC runtime, a
program/thread must be registered with it using the
ERXRegister
function. Hence ERXRegister
must be the first call to
the EntireX RPC runtime and ERXUnregister
the
last. The number of registrations and unregistrations should be symmetric for
every thread, otherwise the thread's resources that are held by the EntireX RPC
runtime will not be freed. However, successful unregistration of the last
thread within a process will free all EntireX RPC runtime resources.
Each thread of a process has to register separately with the EntireX RPC runtime. After registration the EntireX RPC runtime maintains on a per-thread basis
codepage settings, see ERXSetCodepage
and
Using Internationalization with the C Wrapper
broker security settings, see
ERXSetBrokerSecurity
,
ERXSetSecurityToken
and
Using EntireX Security
the RPC conversation context, if any RPC conversation is ongoing, see
ERXConnect
and
Using Conversational RPC
the last error, which can be retrieved using
ERXGetLastError
The following limitations and restrictions also apply:
Up to 256 threads can be registered in parallel within a process.
Multiple registration up to 32,767 per thread before unregistration is possible but not recommended.
All functions provided by the EntireX RPC runtime to handle the variable-length data types and unbounded arrays can be used without registration.
Functions to handle variable-length data types are defined in the header file erxvdata.h and are prefixed with "erxVData".
Functions to handle unbounded arrays are defined in the header file erxarray.h and are prefixed with "erxArray".
The EntireX C Wrapper API provides an interface to examine the
version of the RPC Runtime, see ERXGetVersion
.
If you generate interface objects according to the instructions given in Using the C Wrapper for the Client Side, a function to examine the interface object version on a per-library basis is also generated:
int ERX_CALL_DECLARATION GetVersionEXAMPLEStub( char *pMessage, size_t uMessageLength );
Calling this function will provide you with the version and patch level under which the interface object was generated.
EntireX C Wrapper Version=9.0.0, Patch Level=0
There are several possibilities to trace the EntireX C Wrapper. See Tracing webMethods EntireX under UNIX | Windows | BS2000 | z/VSE.
The EntireX C Wrapper runtime supports RPC clients in multithreaded environments. Every thread can establish its own RPC and broker context for communication, which is separate from every other thread's context, see also Using the RPC Runtime.
The functions ERXSetContext
and ERXGetContext
together with client interface objects generated using the instructions given
in Using the C Wrapper in Multithreaded Environments (UNIX, Windows) assist in
programming multithreaded RPC clients.
The ERXSetContext
function can be executed
prior to any business logic to provide the RPC and broker context individually
on a per-thread basis. ERXSetContext
saves the context information in a
structure ERX_CONTEXT_BLOCK
.
The client interface object picks up the context from the calling thread using
the reverse function ERXGetContext
. Hence legacy
applications may not be changed to transport this information.
Additional Notes:
To use the ERXSetContext
and
ERXGetContext
functions, client interface objects must
be generated with the check box Multithreaded Client
switch. See Generate C Source Files from Software AG IDL Files.
A maximum of 256 threads are supported in parallel.
The ERXSetContext
function can be called
multiple times (within the same thread). This also makes it possible to change
RPC and broker context with each RPC request.
Nothing needs to be considered for servers. EntireX RPC servers support multithreading without any further activities.
The library name sent with the RPC request to the EntireX RPC or the
Natural RPC Server is specified in the IDL file (see library-definition
). When the RPC is executed, this library
name can be overwritten.
To overwrite the library, an EntireX C Wrapper client must do the following:
Set the medium ERX_TM_BROKER_LIBRARY
in the ERX_SERVER_ADDRESS
structure (see ERX_SERVER_ADDRESS
under API Data Descriptions).
Specify the correct library in the ERX_SA_BROKER_LIBRARY
structure
in the szLibraryName
parameter.
To force the library to be considered by Natural RPC Server
Set the parameter cNaturalLogon
to
"ERX_NATURAL LOGON_YES
" in the ERX_SA_BROKER_LIBRARY
structure.
Warning: Natural and EntireX RPC servers behave differently regarding the library name. |
See Natural Logon or Changing the Library Name.
The following functions are used to send and receive the
variable-length data types (IDL data types AV, BV, KV and UV). All
variable-length data is controlled by so-called VData
instances. A VData
instance is a handle (pointer) to a memory location encapsulated in the
erxVData...
functions in the EntireX RPC
runtime.
A VData
instance has the following type definition:
typedef void * ERX_HVDATA; /* Handle of VData
instance */
See the following overview of VData
functions.
Task | Function |
---|---|
Allocate a new VData instance
|
erxVDataAllocBytes erxVDataAllocString erxVDataAllocWideString |
Remove a VData instance
|
erxVDataFree |
Get the contents held by a VData instance
|
erxVDataGetByteAddress erxVDataGetLength erxVDataGetString erxVDataGetWideString |
Assign new contents to the VData instance
|
erxVDataCopy erxVDataReAllocBytes erxVDataReAllocString erxVDataReAllocWideString erxVDataReset |
Before issuing the RPC request, allocate all VData
instances including
the instances for direction out (which is returned by the RPC server only), see attribute-list
.
To allocate and create VData
instances
For the directions in and inout, use erxVDataAllocBytes
(IDL data
type BV and KV), erxVDataAllocString
(IDL data type AV) or
erxVDataAllocWideString
(IDL data type UV) with the appropriate parameters to
allocate the VData
instances.
For the direction out use erxVDataAllocBytes(NULL,0)
(IDL data type
BV and KV), erxVDataAllocString(NULL)
(IDL data type AV) or
erxVDataAllocWideString(L"")
(IDL data type UV)to create an empty VData
instance, which will contain the data returned by the server.
Following the RPC request, you can examine the server reply.
To examine the server reply
Use the functions erxVDataGetString
(IDL data type AV),
erxVDataGetWideString
(IDL data type UV) and erxVDataGetLength,
erxVDataGetByteAddress
(IDL data type BV and KV).
To remove VData
instances
Use the function erxVDataFree
if they are no longer needed.
When your implemented server is called, all VData
instances are
allocated by the RPC C runtime and RPC Server. The data sent by the client can
be examined in the server program (in the same way the client does upon server
reply). The RPC Server and the RPC C runtime will remove the VData
instances if
they are no longer needed. Do not remove any VData
instances in server programs
yourself!
To examine the client data
Use the functions erxVDataGetString
(IDL data type AV),
erxVDataGetWideString
(IDL data type UV) and erxVDataGetLength
, erxVDataGetByteAddress
(IDL data type BV and KV).
To assign data to be returned
Use the functions erxVDataReAllocBytes
(IDL data type BV and KV),
erxVDataReAllocWideString
(IDL data type UV) and erxVDataReAllocString
(IDL
data type AV).
The following functions are used to send and receive unbounded array data types of EntireX RPC (data types defined with V in the indices). All unbounded arrays are controlled by so-called arrays instances. An arrays instance is a handle (pointer) to a memory location encapsulated by the EntireX RPC Runtime.
An array instance has the following type definition:
typedef void * ERX_HARRAY; /* Handle of Array instance */
See the following overview of functions for use with unbounded arrays.
Task | Function |
---|---|
Allocate a new array instance | erxArrayAlloc |
Remove an array instance | erxArrayFree |
Get the contents of an array instance | erxArrayGetElement |
Assign new contents to an array instance | erxArrayCopy erxArrayReset erxArraySetElement |
Get the characteristics of an array instance | erxArrayGetAttributes erxArrayGetBounds erxArrayGetDimension erxArrayGetElementLength erxArrayGetTypeCode |
Change upper bounds of an array instance | erxArrayRedimAll erxArrayRedimVector |
Before calling the client interface object (that is, before issuing the remote procedure call) allocate all array instances and create instances for out data. You cannot change any type, attribute, length or dimension. When the instances are created, only the upper bounds can be changed.
For the directions in and inout, use
erxArrayAlloc
with appropriate parameters to allocate
an array instance. For the direction out, create an array instance of correct
type, attributes, length and dimension with all upper bounds set to 0. This is
an empty array instance with no elements. Upon return it will contain the
elements assigned by the server.
EntireX RPC supports unbounded arrays which must not necessarily be a square (when 2-dimensional) or a cube (when 3-dimensional). Any vector within any dimension could have different upper bound settings. Such an array could be created in two ways:
Start with an empty array and set the upper bounds of the first
dimension with erxArrayRedimVector
. Subseqeuently loop
through this dimension and set any vector of the second dimension using also
erxArrayRedimVector
. If it is a 3-dimensional array,
do the same with the third dimension.
Create a square (2-dimensional) or cube (3-dimensional) with
erxArrayAlloc
or
erxArrayRedimAll
and subsequently deform the array
with erxArrayRedimVector
.
Data to be sent can be assigned using the function
erxArraySetElement
as long as the index is within the
current upper bounds. Otherwise an error will occur. Because any vector of any
dimension could have different upper bound settings, the upper bounds must be
examined separately for every vector. See the following code fragment:
int i,j,k; ERX_HARRAY hArray; ERX_ARRAY_INDEX uArrayIndex[3]; ..... for (i=0;i<erxArrayGetBounds(hArray,(unsigned int)1,NULL);i++) { uArrayIndex[0] = i; for (j=0;j<erxArrayGetBounds(hArray,(unsigned int)2,uArrayIndex);j++) { uArrayIndex[1] = j; for (k=0;k<erxArrayGetBounds(hArray,(unsigned int)3,uArrayIndex);k++) { Data = ...; uArrayIndex[2] = k; rc = erxArraySetElement( hArray, uArrayIndex, &Data ); } } }
To examine the data received from the server the same scheme can be used:
int i,j,k; ERX_HARRAY hArray; ERX_ARRAY_INDEX uArrayIndex[3]; ..... for (i=0;i<erxArrayGetBounds(hArray,(unsigned int)1,NULL);i++) { uArrayIndex[0] = i; for (j=0;j<erxArrayGetBounds(hArray,(unsigned int)2,uArrayIndex);j++) { uArrayIndex[1] = j; for (k=0;k<erxArrayGetBounds(hArray,(unsigned int)3,uArrayIndex);k++) { uArrayIndex[2] = k; rc = erxArrayGetElement( hArray, uArrayIndex, &Data ); ... = Data; } } }
Remove previously created array instances (if they are no longer
needed) with the function erxArrayFree
.
When the server is called, all array instances are allocated by the EntireX RPC Runtime and EntireX RPC Server.
The data sent by the client can be examined in the server program the same way the client examines data upon server reply.
The upper bounds of the array instance can be changed with the
erxArrayRedimAll
or
erxArrayRedimVector
function before setting any return
data:
When you use the erxArrayRedimAll
function,
the result will be an array in the form of a vector (1-dimensional), a square
(2-dimensional) or a cube (3-dimensional). Thus all vectors of a dimension have
the same upper bounds. Subsequently with the
erxArrayRedimVector
the square or cube can be
deformed.
You can also remove all elements of the unbounded array. This
results in an unbounded array with no elements when setting the bounds
parameter of erxArrayRedimAll
to
"0". Afterwards you can set the upper bounds of the
first dimension with erxArrayRedimVector
.
Subseqeuently loop through this dimension and set any vector of the second
dimension also using erxArrayRedimVector
. If it is a
3-dimensional array, do the same with the third dimension. You cannot change
any type, attribute, length or dimension. Only upper bounds can be changed.
Data to be returned can be assigned using the function
erxArraySetElement
the same way the client does before
send.
Important:
Do not remove any array instances in server
programs.
It is assumed that you are familiar with the concepts of conversational and non-conversational RPC. See Common Features of Wrappers and RPC-based Components.
To use conversational RPC
Open a conversation with the ERXConnect
function call (see
ERXConnect
).
Save the server address ERX_SERVER_ADDRESS
and reuse it for
the complete RPC conversation.
Issue your RPC requests as within non-conversational mode using the generated interface objects. Different interface objects can participate in the same RPC conversation.
To abort a conversational RPC communication
Abort an RPC conversation unsuccessfully with the function call
ERXDisconnect
.
To close and commit a conversational RPC communication
Close the RPC conversation successfully with the function call
ERXDisconnectCommit
.
Warning: Natural and EntireX RPC servers behave differently when ending an RPC conversation. |
See Conversational RPC.
EntireX C Wrapper Applications which require security can use the security services offered by EntireX Security. See Security Solutions in EntireX for a general overview.
To use EntireX Security
Specify a user ID and password in the parameters szUserId
and
szPassword
of the ERX_CLIENT_IDENTIFICATION
structure.
Set security with the function
ERXSetBrokerSecurity
to
force a secure call to a broker running with EntireX Security. You can use
the same values as for broker ACI field KERNELSECURITY
.
See KERNELSECURITY
under Broker ACI Fields. The function works together with
any broker kernel version that supports EntireX Security, regardless of the
ACI version used.
Note:
The broker's security token is maintained inside the EntireX RPC
Runtime on a per-thread basis, see Using the RPC Runtime. If you are communicating
with more than one broker in a single thread:
you have to save the broker's security token provided in the
ERX_CLIENT_IDENTIFICATION
structure after an ERXLogon
function call
you have to provide the correct previously saved Broker's security
token with the ERXSetSecurityToken
function to the
RPC Runtime before calling one of the following functions:
ERXCall
ERXConnect
ERXDisconnect
ERXDisconnectCommit
ERXLogon
ERXLogoff
ERXTerminateServer
ERXIsServing
ERXWait
Other functions are executed locally and do not communicate with the Broker, the Broker's security token is not required.
A Natural RPC Server may run under Natural Security to protect RPC requests. See Natural Security.
To authenticate an EntireX C Wrapper client against Natural Security
Specify a user ID and password in the parameters szUserId and
szPassword of the ERX_CLIENT_IDENTIFICATION
structure.
If different user IDs and/or passwords are used for EntireX Security
and Natural Security, use the parameters szRpcUserId
or
szRpcPassword
to provide the user IDs and/or passwords
for Natural Security.
To force an EntireX C Wrapper Client to log on to a specific Natural library
Set the medium ERX_TM_BROKER_LIBRARY
in the
ERX_SERVER_ADDRESS
structure.
Specify the correct Natural library in the ERX_SA_BROKER_LIBRARY
structure in the szLibraryName
parameter.
Set the parameter cNaturalLogon
to
"ERX_NATURAL LOGON_YES"
in the ERX_SA_BROKER_LIBRARY
structure.
See also Natural Logon or Changing the Library Name in this document.
RPC client applications can use Secure Sockets Layer/Transport Layer Security (SSL/TLS) as the transport medium. The term "SSL" in this section refers to both SSL and TLS. RPC-based clients are always SSL clients. The SSL server can be either the EntireX Broker or Direct RPC in webMethods Integration Server (IS inbound). For an introduction see SSL/TLS and Certificates with EntireX in the EntireX Security documentation.
With the C Wrapper, the SSL parameters (e.g. certificates) are provided in the ERX_CLIENT_IDENTIFICATION
structure.
To use SSL
To operate with SSL, certificates need to be provided and maintained. Depending on the platform, Software AG provides default certificates, but we strongly recommend that you create your own. See SSL/TLS Sample Certificates Delivered with EntireX in the EntireX Security documentation.
Specify the Broker ID, using one of the following styles:
URL Style, for example:
ssl://localhost:2010
Transport-method Style, for example:
ETB024:1609:SSL
If no port number is specified, port 1958 is used as default.
Specify SSL parameters on the pSSLParameter
parameter in the ERX_CLIENT_IDENTIFICATION
structure, for example:
"VERIFY_SERVER=N&TRUST_STORE=c:\\certs\\CaCert.pem"
If the SSL client checks the validity of the SSL server only, this is known as one-way SSL. The mandatory trust_store
parameter
specifies the file name of a keystore that must contain the list of trusted certificate authorities for the certificate of
the SSL server.
By default a check is made that the certificate of the SSL server is issued for the hostname specified in the Broker ID.
The common name of the subject entry in the server's certificate is checked against the hostname. If they do not match, the
connection will be refused.
You can disable this check with SSL parameter verify_server=no
.
If the SSL server additionally checks the identity of the SSL client, this is known as two-way SSL. In this case the SSL server requests a client certificate
(the parameter verify_client=yes
is defined in the configuration of the SSL server).
Two additional SSL parameters must be specified on the SSL client side: key_store
and key_passwd
.
This keystore must contain the private key of the SSL client. The password that protects the private key is specified with
key_passwd
.
The ampersand (&) character cannot appear in the password.
SSL parameters are separated by ampersand (&). See also SSL/TLS Parameters for SSL Clients.
Make sure the SSL server to which the RPC component connects is prepared for SSL connections as well. The SSL server can be EntireX Broker, Broker SSL Agent, or Direct RPC in webMethods Integration Server (IS inbound). See:
EntireX C Wrapper Applications may compress the messages sent to and received from the broker.
To use compression
Specify a compression level in the
ERX_CLIENT_IDENTIFICATION
structure. Possible compression levels are identical to the broker ACI field
COMPRESSION
.
See COMPRESSLEVEL
.
For RPC clients, the RPC runtime itself does not convert your application data. The application's data is shipped and received as given. The application must ensure the encoding of the data matches the codepage sent to the broker.
Under the Windows operating system:
The RPC runtime assumes by default the data is given in the encoding of the Windows ANSI codepage configured for your system.
A codepage identifier of this Windows ANSI codepage is automatically transferred to tell the broker how the data is encoded,
even if no codepage name is provided with function ERXSetCodepage
, see API Function Descriptions.
If you want to adapt the Windows ANSI codepage, see the Regional Settings in the Windows Control Panel and your Windows documentation.
If you want to encode the data different to your Windows ANSI codepage, provide the data in the desired encoding and provide
the codepage name with function ERXSetCodepage
. During receive, decode the data if necessary.
Under all other operating systems:
The RPC runtime does not automatically send a codepage identifier to the broker.
It is assumed the broker's locale string defaults match. See Locale String Mapping.
If they do not match, provide the correct codepage name with function ERXSetCodepage
.
Enable character conversion in the broker by setting the service-specific attribute CONVERSION
to "SAGTRPC
".
See also Configuring ICU Conversion under
z/OS |
UNIX |
Windows |
BS2000 |
z/VSE.
More information can be found under Internationalization with EntireX.