This chapter provides an overview of the RTR C++ foundation classes and describes concepts that apply to application development using the this application programming interface (API). It includes conceptual descriptions of client and server interaction and application processing. Detailed information is provided on each class and its associated methods in later chapters of this manual. For code examples and implementation information, see the Design and Implementation chapter of this manual.
The C++ foundation classes enable you to implement new RTR client and server applications, or to integrate specific classes into existing applications to add additional functionality.
RTR concepts have been mapped to and implemented by the set of foundation classes for handling system management and the needs of business applications.
Figure 1-1 shows the C++ foundation classes. Management classes represent RTR, facilities, partitions, and key segments (part of the partitioning classes in Figure 1-1) whereas application classes represent transactions, data, messages and events.
The primary application classes include client classes, server classes, and data classes that are common to both client and server classes. There are also server and client transaction property classes.
You use management classes to implement applications that can help manage RTR. You use application classes to implement client and server applications. However, client and server applications can also use the management classes to dynamically set up RTR facilities and partitions.
Figure 1-1: C++ Foundation Classes
Facility, partition, and transaction property classes include methods that provide access to facilities, partitions, and transactions. These classes enable a program to obtain additional information on a facility, partition, or a transaction. Transaction property classes are useful for transaction recovery and for obtaining and setting transaction states.
Property classes work with other foundation classes in new applications; they can also be used independently in legacy RTR applications. They do this by using information that existing RTR applications already have, including transaction IDs (tids), facility names, and partition names.
RTR C++ foundation application classes include:
Data classes are common classes for passing data between client and server applications.
(Client and server transaction property classes are included within the client application classes and server application classes, respectively.)
To use RTR application classes, it is useful to understand RTR concepts necessary for implementing application solutions with the C++ API, C++ API-specific information, and object-oriented concepts.
Figure 1-2 illustrates the client and server classes and the paths through which they typically communicate. (There are design alternatives to the illustrated path.) TransactionController objects control transactions. Communication between client and server applications is through messages and events sent and received by the RTR application. Data objects (instances of data classes) carry these messages and events between RTR clients and servers.
Figure 1-2: C++ API Classes
The principal application classes are the transaction controller classes and data classes. A transaction controller object manages a transaction. The RTRData-derived data object is the common means through which client and server applications interact. A message handler encapsulates the data. Most events are not related to transactions. A message is sent from a client to a server or a server to a client (1-to-1). An event can go from one client or server to many clients and servers.
In RTR, a transaction is a logical grouping of messages.
A transaction is controlled by a TransactionController object. The client transaction controller class (RTRClientTransactionController) creates single instances of a transaction. The server transaction controller class (RTRServerTransactionController) manages single instances of a transaction.
A transaction controller object:
Typically, a transaction controller object processes multiple consecutive transactions, but there is at most one active transaction in a transaction controller object at any one time.
A transaction controller:
Applications use data objects to carry data between RTR clients and servers. Thus, the data classes are common to both client and server applications. RTRData is the base class from which four kinds of data are derived:
The class factory, RTRClassFactory, creates instances of data classes based on the content of a transaction controller Receive call for a message or event.
Communication between client and server applications is through messages and events. Data objects contain these messages and events sent and received by RTR clients and servers.
Figure 1-3 illustrates the data classes and their relationships to the RTRData base class and a memory buffer. For example, the base class of RTRStream is RTRData and the base class of RTRApplicationMessage is RTRStream.
Figure 1-3: Data Classes
An application wanting to send or receive data, specifies an RTRData object. The mechanism for sending and receiving is different as follows:
When calling SendApplicationMessage on a transaction controller, the caller specifies an RTRApplicationMessage.
When calling the Receive method, the application supplies an RTRData pointer to NULL. When the transaction controller determines the type of data which is about to be obtained it calls a class factory to create an instance of the appropriate object.
After a successful call to the Receive method, the RTRData pointer contains one of the following kinds of objects:
The RTRClassFactory class creates the above data objects. Based on the type of message contained on the transaction controller Receive call the class factory creates an instance of the appropriate data class. The class factory also enables you to customize the behavior of data object creation. An application may derive its own RTRClassFactory class and register it with the transaction controller. In this case, the transaction controller calls the application's class factory to create the data object.
Dispatch Methods and Handlers
Since all Data classes are derived from RTRData, an application can treat the data polymorphically, especially when receiving data on the server.
For example:
ServerTransactionController ServerTransactionController;
RTRData *pDataBeingReceived = NULL;
while (true)
{
// Receive some data
ServerTransactionController.Receive(&pDataBeingReceived);
// No need to determine what we received.
// Just call Dispatch()
pDataBeingReceived->Dispatch();
}
The RTRData class has a pure virtual method named Dispatch(). This means that all classes derived from RTRData provide an implementation of Dispatch(). This implementation of Dispatch, which is provided by the derived class, determines the exact message or event number that it contains and calls the appropriate method in the handler.
The message and event handler classes are:
An application may derive its own class from any or all of these handlers to provide its own custom handling of the specific messages and events.
Data objects carry messages between clients and servers. These messages are of two types:
Data objects carry events between clients and servers. These events are of two types:
Application events can be transmitted only within the RTR facility in which they are defined. Application events cannot be sent between facilities or outside RTR.
For client and server applications to work together, you create a ClientTransactionController in the client application and a ServerTransactionController in the server application. These transaction objects communicate by using objects derived from the RTRData class.
RTR applications need to define an application-level protocol to pass data between client and server. From the point of view of a client or server application, the application protocol is just data. The data object encapsulates the application protocol as shown in Figure 1-4. In this example, a protocol is defined for sending data between a client and server application that processes book orders, as in the book ordering sample application. This data protocol includes fields for ISBN number, book-price, book-name, and author. These fields are contained in a buffer in an RTRData object.
The data protocol is encapsulated in a user-defined ApplicationProtocol class. The ApplicationProtocol class is an (derives from) RTRApplicationMessage, which is an (derives from) RTRStream, which is an (derives from) RTRData object that contains the application protocol in its buffer.
Figure 1-4: RTRData Encapsulation
The data classes are used by both client and server RTR applications. When applications want to send or receive data, they specify an RTRData-derived object.
Figure 1-5 illustrates client/server deployment and interaction. The numbered steps represent client logic within the client application and server logic within the server application. For a more detailed description of transactional messaging, see the RTR Application Design Guide.
Figure 1-5: Client/Server Interaction
An RTR transaction processing system consists of separate client applications and server applications. This example demonstrates a client sending a message to the server and the server responding, but the server calls the first Receive. The logical interaction between client and server is as follows:
For more information on client and server messaging, see the RTR Application Design Guide.
An instance of the class RTRClassFactory is an object that creates other data objects. The class RTRClassFactory has four methods:
Client and server transaction controllers use the class factory when receiving a message or event. Every transaction controller has a class factory. If the application does not register its own, a default is provided.
When the application calls Receive, the transaction controller determines what kind of message or event is about to be received, and then calls the appropriate method in the application-derived and registered class factory object (for example, CreateRTRMessage). This method creates the appropriate data object (for example, an RTRMessage object) and returns it to the transaction controller. The transaction controller copies the incoming data into the data object returned from the class factory and returns back to the application's call to Receive().
Applications can override the methods of the RTRClassFactory and return their own customized versions of the data classes.
Receiving an Application Message
Typical client requests processed by a server application are sent and received as RTRApplicationMessage objects. The most common method for implementing business logic data protocols is deriving from the RTRApplicationMessage class. In Figure 1-6, AM represents an incoming application message.
Figure 1-6: Receiving an Application Message
In Figure 1-6:
Receiving a User-Defined Application Message
User-defined application messages are sent and received as RTRApplicationMessage objects. In Figure 1-7, AM represents an incoming application message.
Figure 1-7: Receiving a User-Defined Application Message
In Figure 1-7:
Note that the derived class factory does not have to handle all the messages. It is only handling the application message (AM) and taking all of the other default methods (for example, CreateRTRMessage).
For an added level of functionality, the RTRStream data class allows for easier access to the data passed between the client and server applications. This class provides methods with which you can read from and write to the data buffer contained in RTRData. With these methods, maintaining offset into the buffer is automatic.
The RTRStream class allows the serialization and deserialization of objects. For example, if a client application called,
RTRStream::WriteToStream("WarandPeace");
RTRStream::WriteToStream("Tolstoy");
and a server then called,
RTRStream::ReadFromStream(pString1);
RTRStream::ReadFromStream(pString2);
pString1 would point to "WarandPeace" and after the second read, pString2 would point to "Tolstoy."
For large amounts of data to be sent and received, a WriteToStream method takes a void pointer to the length of the buffer.
Figure 1-8 illustrates the client, data, and server classes in the application classes and shows their parallelism. Data classes are common to both client and server applications.
Figure 1-8: Application Classes
Table 1-1 shows application class categories and their descriptions. Table 1-2 lists the application data classes that are common to both client and server applications. Except for data classes, the class categories describe the characteristics of the associated client and server classes (for example, the Transaction Controller class category in Table 1-1 describes the RTRServerTransactionController and RTRClientTransactionController classes). For detailed descriptions of individual foundation classes and their associated methods, see the Application Classes chapter of this manual.
Table 1-1: Application Class Category Descriptions
Class Category |
Description |
Transaction Controller |
The transaction controller manages each transaction and also manages the messages and events associated with that transaction.
|
Transaction Properties |
The RTRTransactionProperties class:
|
Event Handlers |
Use RTREventHandler classes to obtain information about a transaction such as whether a server is primary, standby or shadow. The RTREventHandler class:
You must register an event handler with the RegisterHandlers method |
Message Handlers |
Message handlers can be used for all transactions and all application data. The RTRMessageHandler class:
RTRMessageHandler lets you override only messages you want to use. For example, OnApplicationMessage can be implemented with business-logic-specific objects such as OnStockBuy or OnStockSell. |
Table 1-2: Data Class Descriptions
Class Category |
Description |
RTRMessage |
The RTRMessage class:
If an application has not registered a class factory, the application calls
|
RTREvent |
The RTREvent class:
If an application has not registered a class factory, the application calls
|
The RTRData class is used to send and receive messages and events.
|
|
RTRApplicationMessage |
The application:
|
RTRApplicationEvent |
The application:
|
RTRStream |
The RTRStream class:
|
RTRClassFactory |
The RTRClassFactory class creates instances of the data classes:
An application registers its own class that is derived from the |
Management classes manage the environment in which an RTR application executes, not the business-logic infrastructure of the application. This allows you to do in a program what formerly had to be done at the system management command level.
Facility Management
Managing facilities is based on three concepts provided as separate foundation classes:
A facility manager creates and deletes facilities, and adds and removes facility members based on facility name.
Facility properties represent the information and properties of a single facility.
Facility members represent the individual members of a particular facility. A facility member is both a role and a node combined, because a node can have more than one role. For example, a nodename can represent three members by being defined three times with the same node but with different roles (backend, frontend, router).
For general information on RTR facilities, see RTR Getting Started and the RTR System Manager's Manual.
Partitions and Key Segments
One of the benefits of the routing capability in RTR is that it enables you to partition your data across multiple servers and nodes for increased performance. Within an application, the partition determines how messages are routed from clients to servers. RTR routes messages to the correct partition on the basis of an application-defined key.
The contents of a message determine its destination. The router tracks the location of data partitions and sends client messages to the appropriate server for processing. The routing key, or key segment, is embedded within the RTR message.
The foundation classes provide the object-oriented framework to implement data partitioning with the following classes:
A partition manager creates and deletes partitions, and returns properties for individual partitions based on partition name.
Partition properties represent individual partitions within RTR and provide statistics for a partition.
A key segment object defines the range of a partition.
An RTRKeySegment object specifies a data key range and is associated with a partition when a Partition Manager creates a partition.
Figure 1-9 illustrates the relationship between RTR entities and partition classes. Partition classes refer to an RTR partition. As the figure illustrates, the actual partition resides in RTR, not in the foundation class objects. Methods within the partition classes can create and delete partitions, and get partition properties for the RTR partitions.
Figure 1-9: Partition Objects and RTR
Management Classes Descriptions
Figure 1-10 shows the management class categories and their classes. These classes can be used in new applications or integrated into existing legacy applications.
Figure 1-10: Management Classes
With the management classes, you can create a facility or a partition programmatically instead of using the command language interface (CLI). For legacy applications, you can write management routines to create your application environment in an existing RTR C-language application.
Facility, management, and partition information exists in RTR. The management classes access the information from RTR.
Table 1-3 describes the management classes. For detailed descriptions of individual classes and their associated methods, see the Management Classes chapter of this manual.
Table 1-3: Management Class Descriptions
Class |
Description |
RTRFacilityManager |
Is used to manage the creation, deletion, and viewing of facilities |
RTRFacilityMember |
Represents a member of a particular facility. The member can be any Knows the relationship to the local node. Provides member functions to evaluate connectivity. For example, IsConnectedToLocalNode returns a boolean return to a query such as: |
RTRFacilityProperties |
Represents a single facility that exists within RTR. Knows other members in the facility. |
Manages the creation and deletion of partitions based on |
|
Defines and represents the key range of a partition associated with |
|
RTR |
The RTR class represents RTR on the local node and performs
|
RTRCounter |
Enables an application to define and manipulate a counter within
|
RTRBackendPartitionProperties |
Supplies information about a partition, once it has been created. Can be used by new or existing applications. Can be used to obtain information on partitions created at the Represents a single partition that exists within RTR. Since a Provides statistics for a partition. |
You can use either of two processing models to implement client and server applications. Depending on which processing model you use, you implement the classes differently. The two processing models are:
Table 1-4 compares the two processing models. These comparisons apply to both client and server. The sample application and code examples in this book use event-driven processing in server applications, and polling in client applications.
Table 1-4: Transaction Processing Models Compared
Processing |
What You Get |
Programming Logic |
Message and Event Handling |
Event-Driven |
Default handling of all RTR messages and events. |
Create a loop containing Receive() and Dispatch() calls. |
Messages and Events are handled by the MessageHandler and EventHandler objects. |
Polling |
RTRData methods that allow for user-implemented detection of incoming data and development of message and event handling. |
Use RTRData methods to detect incoming data types. Develop logic to handle all possible messages and events. |
User-implemented logic in place of MessageHandler and EventHandler classes. |
Figure 1-11 shows the steps in the event-driven model of transaction processing as used in a server application.
Figure 1-11: Event-Driven Server Processing
In the event-driven model, the application is informed when there is something for it. RTR automatically sends messages to the server and the server runs a transaction, using the Receive and Dispatch methods within a while loop. Business logic resides in the message and event handlers. The event-driven model is the recommended method for implementing server applications.
As shown in Figure 1-11, the sequence of operations is as follows:
User-implemented logic and methods are stored in the data object. Checking for RTR-generated data, retrieving messages, and retrieving events are all done for you automatically, if you call Dispatch. For example, on a Receive call, if the message is rtr_mt_msgn, then calling Dispatch calls OnApplicationMessage by default. OnApplicationMessage is a method in the RTRServerMessageHandler and RTRClientMessageHandler classes.
Business logic is typically implemented in the server message handler. However, you can implement business logic in other ways as well.
Using the event-driven model implements the following mechanism:
The Data Object is passed on this call. All handler methods have two parameters: a message type, and a pointer to the TransactionController from which the message came. Data Objects, which are stateless, are not tied to a TransactionController; they can be handled by different TransactionControllers. Thus, using a TransactionController does not restrict client applications.
This sequence is shown in Figure 1-12.
Figure 1-12: Event-Driven Processing Example
Message and Event Handling
This section provides event and message handling examples that are processed based on what RTR message or event is received on a Receive call. Depending on the message received, the subsequent process is different, as shown in Table 1-5.
Table 1-5: Message and Event Handling Examples
If the message received is: |
Then: |
rtr_mt_msgn |
The Data Object goes to the Message Handler by the OnApplicationMessage(Data Object) method. Then, in the Message Handler, the Data Object is processed by OnApplicationMessage. |
rtr_mt_rejected |
The Data Object goes to the Message Handler using the OnRejected(Data Object) method. Then, in the Message Handler, the Data Object is processed by OnRejected. |
rtr_mt_prepare |
The Data Object is dispatched to be handled internally. Application business logic does not need to know about RTR Prepares. In the C++ API, Prepares are transparent. |
EVTNUM_SRPRIMARY |
The Data Object goes to the Event Handler using the OnServerIsPrimary(Data Object) method. Then, in the Event Handler, the Data Object is processed by OnServerIsPrimary. |
RTRMessageHandler and RTREventHandler are the default handlers. Processing is done by an application's derived business logic. Default handlers do not keep state, so the application must return to BackendPartitionProperties to get state.
Example 1-1 illustrates the looping implementation for event-driven processing.
Example 1-1: Receive Loop
ServerTransactionController ServerTransactionController;
RTRData *pDataBeingReceived = NULL;
while (true)
{
// Receive some data
ServerTransactionController.Receive(&pDataBeingReceived);
// No need to determine what we received.
// Just call Dispatch();
pDataBeingReceived->Dispatch();
}
Figure 1-13 shows the steps in the polling model of transaction processing as used in a client application.
Figure 1-13: Polling Processing Model
The polling model processing steps are:
User-implemented logic handles all possible messages, events, and serialized objects using RTRData methods.
In the polling model, you create a receive loop to poll for incoming data. Messages or events are received one at a time, and Register does not connect message and event handlers. The server asks RTR for a request.
You can still check the data object and code tasks as follows:
As Figure 1-13 illustrates, in common with the event driven model, you use a subset of the same objects, but Register does not connect the message and event handlers.
Example 1-2 illustrates an implementation for the polling model of processing. As this example illustrates, the flow is controlled by the object that is polling for a message or event from RTR with Receive.
Example 1-2: Polling Model Example
ServerTransactionController ServerTransactionController;
RTRData *pDataBeingReceived = NULL;
while (true){
// Receive some data
ServerTransactionController.Receive(&pDataBeingReceived);
// Since handlers are not being used, determine what is
// received. Application-generated message or event.
// RTR-generated message or event.
if (true = pDataBeingReceived->IsApplicationMessage())
{
// Process accordingly
}
else
if (true = pDataBeingReceived->IsApplicationEvent())
{
// Process accordingly
}
else
if (true = pDataBeingReceived->IsRTRMessage())
{
// Process accordingly
}
else
if (true = pDataBeingReceived->IsRTREvent())
{
// Process accordingly
}
}
Base Classes Message and Event Mapping
The foundation class message and event handler methods are provided in base classes. You derive from them and choose which ones to use in your implementation. Base handlers are used by default, if you do not derive from them.
Figure 1-14 illustrates RTR messaging between client and server. RTR messages are contained in the data object passing between the client and server. With event-driven processing, the class factory creates the appropriate data object.
Figure 1-14: RTR Messaging Between Client and Server Applications
To connect, the client registers a facility and the server registers a facility and a partition. The client transaction ends with rtr_mt_accepted or rtr_mt_rejected. The server transaction ends with the AcknowledgeTransactionOutcome method.
When Dispatch is called, certain handlers are called for transactions on the client and server, as shown in the following tables.
When Dispatch is called, certain handlers are called for transactions on the client, as shown in Table 1-6.
Table 1-6: Client Handlers by Message Type
When the RTR Message Type is: |
Contained in: |
The RTRClientMessageHandler Call is: |
rtr_mt_accepted |
RTRMessage |
OnAccepted |
rtr_mt_reply |
RTRApplicationMessage |
OnApplicationMessage |
rtr_mt_rttosend |
RTRMessage |
OnReturnToSender |
rtr_mt_prepared |
RTRMessage |
OnAllPreparedTransaction |
rtr_mt_rejected |
RTRMessage |
OnRejected |
For example, using the event-driven processing model, when RTRData contains rtr_mt_reply, by default, the RTRApplicationMessage Dispatch method calls OnApplicationMessage.
When Dispatch is called, certain handlers are called for transactions on the client, as listed in Table 1-7.
Table 1-7: Client Handlers by Event for RTREvent
When the RTR Event Number is: |
The RTRClientEventHandler Call is: |
RTR_EVTNUM_FACDEAD |
OnFacilityDead |
RTR_EVTNUM_FACREADY |
OnFacilityReady |
RTR_EVTNUM_FERTRGAIN |
OnFrontendGainedLinkToRouter |
RTR_EVTNUM_FERTRLOSS |
OnFrontendLostLinkToRouter |
RTR_EVTNUM_RTRBEGAIN |
OnRouterGainedLinkToBackend |
RTR_EVTNUM_RTRBELOSS |
OnRouterLostLinkToBackend |
RTR_EVTNUM_KEYRANGEGAIN |
OnNewKeyRangeAvailable |
RTR_EVTNUM_KEYRANGELOSS |
OnKeyRangeNoLongerAvailable |
For example, with the event-driven processing model, when RTRData contains RTR_EVTNUM_FACREADY, by default, the RTREvent Dispatch method calls OnFacilityReady.
When Dispatch is called, certain handlers are called for transactions on the server side, as listed in Table 1-8.
Table 1-8: Server Handlers by Message Type
When the RTR Message Type is: |
Contained in: |
The RTRServerMessageHandler Call is: |
rtr_mt_accepted |
RTRMessage |
OnAccepted |
rtr_mt_msg1 |
RTRApplicationMessage |
OnInitialize OnApplicationMessage |
rtr_mt_msg1_uncertain |
RTRApplicationMessage |
OnUncertainTransaction |
rtr_mt_msgn |
RTRApplicationMessage |
OnApplicationMessage |
rtr_mt_prepare |
RTRMessage |
OnPrepareTransaction |
rtr_mt_rejected |
RTRMessage |
OnRejected |
For example, with the event-driven processing model, by default when RTRData contains rtr_mt_msg1, the RTRServerMessageHandler first calls OnInitialize and then calls OnApplicationMessage. With the polling model, use IsMessage in place of Dispatch and implement GetMessageType to handle the message.
A typical series of Server messages processed for a Transaction in an RTRTransactionController object would be as follows:
OnInitialize
OnApplicationMessage
OnPrepareTransaction
OnAccepted
When Dispatch is called, certain handlers are called for transactions on the server side, as listed in Table 1-9.
Table 1-9: Server Handlers by Event
When the RTR Event Number is: |
The RTRServerEventHandler Call is: |
RTR_EVTNUM_BERTRLOSS |
OnBackendGainedLinkToRouter |
RTR_EVTNUM_BERTRGAIN |
OnBackendGainedLinkToRouter |
RTR_EVTNUM_FACDEAD |
OnFacilityDead |
RTR_EVTNUM_FACREADY |
OnFacilityReady |
RTR_EVTNUM_RTRFEGAIN |
OnFrontendGainedLinkToRouter |
RTR_EVTNUM_RTRFELOSS |
OnFrontendLostLinkToRouter |
RTR_EVTNUM_SRSHADOWGAIN |
OnServerGainedShadow |
RTR_EVTNUM_SRSHADOWLOST |
OnServerLostShadow |
RTR_EVTNUM_SRRECOVERCMPL |
OnServerRecoveryComplete |
RTR_EVTNUM_SRPRIMARY |
OnServerIsPrimary |
RTR_EVTNUM_SRSECONDARY |
OnServerIsSecondary |
RTR_EVTNUM_SRSTANDBY |
OnServerIsStandby |
For example, with the event-driven processing model, by default, when RTRData contains RTR_EVTNUM_FACREADY, the RTRServerEventHandler calls OnFacilityReady. With the polling model, use IsEvent in place of Dispatch, and implement GetEventNumber to handle the event.
For more information, see the state diagrams in Appendix C of the RTR Application Design Guide.
Using the C++ API with Existing Applications
When working with existing RTR applications, you can integrate individual C++ foundation classes into existing client or server applications and also write new management routines that work with existing applications. With the C++ foundation classes, there are no migration issues. There is no need to rewrite existing code to integrate C++ foundation classes. Existing client and server applications are linked transparently by RTR .
In existing applications, objects defined in the application can point to instances of foundation classes.
These classes are designed to be used:
Objects defined in your application can point to instances of the foundation classes, and inherit the rich functionality within these base classes.
The C++ foundation classes provide a method for implementing RTR solutions that is easier to use than the C API. The C++ foundation classes:
Classes that Legacy Applications Can Use
Table 1-10 lists the classes that legacy RTR server applications can use to create and manage the environment in which RTR applications run. The second column of Table 1-10 lists the information required to implement instances of these classes.
Table 1-10: Foundation Classes for Legacy Applications
Class |
Requires: |
Setup class:
|
Nothing |
Facility classes:
|
Facility Name Facility Name |
Partition classes:
|
Nothing Nothing |
Property classes:
|
TID (Transaction ID) TID Partition Name Facility Name |
Diagnostic class:
|
Nothing (for new applications) Group Name |
Facility, management, and partition information exists in RTR. The methods within the management and property classes rely on attributes that RTR applications have.
For example, the diagnostic class RTRCounter relies on the following attributes for getting information:
These are all attributes found in RTR.
The RTRBackendPartitionProperties class relies on partition name and facility name; existing applications already know the partition name. This enables you to call methods, such as GetRetryCount, in this class by passing in a partition. For example:
RTRBackendPartitionProperties MyPartition("MyPartitionName");
MyPartition.GetRetryCount();
Encapsulating Application Protocols
Since foundation classes work with existing applications, the protocol for passing data has not changed. As Figure 1-15 illustrates, legacy applications and new applications both use the same protocol for passing data. Thus, all combinations of old and new clients and servers can communicate with each other.
Figure 1-15 C++ API into Existing Applications
The protocol manager represents an object that knows how to send and receive a protocol defined by the application. The protocol is your data. This is achieved by deriving a class from RTRData that knows how to store information (data) in it. RTRData does this by pointing to a buffer.
Figure 1-16 illustrates the data encapsulation in the protocol manager objects that are shown in Figure 1-15.
Figure 1-16: The Protocol Manager Object
For more information on defining a class that encapsulates an application protocol, see the Design and Implementation chapter of this manual.
In the example shown in Figure 1-17, there is an existing server application and a new client application. To have your existing RTR legacy server application communicate with and obtain information from a new C++ client application, you do not need to integrate C++ foundation classes into your server application.
Figure 1-17: Legacy Application Example
Legacy applications do not have a TransactionController but with the RTRServerTransactionProperties and RTRClientTransactionProperties classes, you need only a TID (transaction identifier) to get state information. You obtain the TID with the existing RTR C API using the rtr_get_tid method. You can pass this TID into the RTRServerTransactionProperties and RTRClientTransactionProperties classes.
By using the rtr_get_tid method of the RTR C API to get the TID, you can pass this value to the new C++ API to construct a ServerTransactionProperties object, with this TID as the parameter (ServerTransactionProperties(TID)). Creating an application with this ServerTransactionProperties object enables you to call any member functions within the ServerTransactionProperties class, such as GetTransactionState and GetFacility.
Compiling and Linking your Application
All client and application programs must be written using C, C++, or a language that can use RTR C++ API calls. Include the RTR data types and error messages file rtrapi.h in your compilation so that it will be appropriately referenced by your application. For each client and server application, your compilation/link process is as follows:
This process is illustrated in Figure 1-18. In this figure, Library represents the RTR C++ API shareable images (OpenVMS), DLLs (Win32), and shared libraries (UNIX).
Figure 1-18: RTR Compile Sequence
The following command lines show the sort of command lines that are needed to compile and link a C++ RTR application that uses the C++ foundation classes, with and without Posix or Microsoft threads. The parts of the command relating to RTR and the parts relating to threads are shown. You may need to specify library directories explicitly if the RTR header files and libraries are not installed in the same directory or in system directories. Note that the exact name of the RTR foundation classes shared library, DLL or shareable image file, and how it is referenced in a command line, varies slightly according to the conventions for the particular platform. Most compilers recognize the extensions .cc .cpp and .cxx for C++ source files.
$ cxx yourapp.cxx
$ cxxlink yourapp,sys$input/opt
librtrcpp/share
$
$ cxx yourapp.cxx
$ cxxlink yourapp,sys$input/opt
librtrcpp_r/share
$
> cl /c -D_MT yourapp.cpp
> link yourapp.obj /out:yourapp.exe rtrcppapi.lib
% cxx yourapp.cc -o yourapp -lrtrcpp
% cxx -pthread yourapp.cc -o yourapp -lrtrcpp
Compilers commonly used in developing RTR applications include those in the following table. For additional information, see the Reliable Transaction Router Software Product Description.
Operating System | Compiler | Compiler Version |
---|---|---|
Microsoft Windows | Microsoft Visual C++ | Version 6.0 SP4 |
OpenVMS Alpha | Compaq C | Version 6.2-006 |
OpenVMS Alpha | Compaq C++ | Version 6.2-035 |
OpenVMS VAX | Compaq C | Version 6.2-003 |
Sun | Workshop Compilers | Version 4.2 |
Tru64 UNIX | Compaq C | Version 6.3-126 |
Tru64 UNIX | Compaq C++ | Version 6.2-033 |