Tuxedo Middleware

Table of Contents

1. Tuxedo introduction

Tuxedo (Transactions for Unix, Extended for Distributed Operations) provides the framework, or middleware, for building scalable multi-tier client/server applications in heterogeneous, distributed environments that extend from the Web to the Enterprise. Using Tuxedo, users can develop, manage, and deploy distributed applications independently of the underlying hardware, operating system, network, and database environment.

Reference: http://docs.oracle.com/cd/E26665_01/tuxedo/docs11gr1/index.html

1.1. Tuxedo history

A brief history of the Tuxedo system:

  • In 1983, the Tuxedo system began as an applied, forward-looking work project within the Bell Laboratories division of AT&T. The target applications for the Tuxedo system were UNIX-based operations support systems within AT&T.
  • In 1989, the Tuxedo system was transferred to the UNIX System Laboratories (USL) division of AT&T, and its client/server framework was offered as a commercial product.
  • In 1993, the Tuxedo system was transferred to Novell, Inc., when Novell acquired USL in 1993.
  • In 1996, BEA Systems, Inc., entered into an exclusive agreement with Novell to distribute and continue development of the Tuxedo system on a variety of computer platforms, including Windows and most UNIX systems.
  • In 2008, Tuxedo became Oracle product along with all other BEA Systems products.

1.2. Tuxedo architecture

Clients and servers are the application-processing components of a Tuxedo system. Server processes provide one or more named services. Client processes can request services without having to know where they are located. The named service feature provides a directory of services that result in the request being routed to one of the servers providing the service. Clients and servers communicate by sending messages. When the clients and servers are distributed over different machines, Tuxedo makes the networking infrastructure by connecting the client and server machines, while keeping the client/server request-response model transparent. Programmers therefore do not have to worry about where the service is located or what the underlying network protocols are. The application's code remains the same whether the clients and servers are running on a single machine or distributed over multiple machines.

1.2.1. 2-Tier VS. 3-Tier Client/Server Models

tuxedo_tiers.gif

Figure 1: 2-Tier VS. 3-Tier Client/Server Models

In 2-tier client/server applications, the business logic is buried inside the user interface on the client or within the database on the server in the form of stored procedures. Alternatively, the business logic can be divided between the client and server. File servers and database servers with stored procedures are examples of 2-tier architecture.

In 3-tier client/server applications, the business logic resides in the middle tier, separate from the data and user interface. In this way, processes can be managed and deployed separately from the user interface and the database. Also, 3-tier systems can integrate data from multiple sources.

The Tuxedo system fits into the middle of the 3-tier client/server model.

2. ATMI (Application-to-Transaction Monitor Interface)

ATMI, for Application-to-Transaction Monitor Interface, is the main API for the Tuxedo system. It includes transaction management functions (routines, verbs); request/response, conversational, queuing, and publish-and-subscribe message-handling functions; service interface functions; and buffer management functions for distributed application communication.

Reference: Tutorials for Developing Tuxedo ATMI Application (pdf backup)

2.1. Creating a Tuxedo ATMI Client

Clients perform the following basic tasks:

  • Clients may need to call tpchkauth() to determine the level of security required to join an application. Possible responses are: no security enabled, application password enabled, application authentication enabled, access control lists enabled, link-level encryption, public key encryption, auditing. (This is optional depending on whether you are using security levels.)
  • Clients call tpinit() to connect to a Tuxedo application. Any required security information is passed to the application as arguments for tpinit().
  • Clients perform service requests.
  • Clients call tpterm() to disconnect from a Tuxedo application.

tuxedo_client.gif

Figure 2: Tasks Performed by a Client

2.2. Creating a Tuxedo ATMI Server

Server Tasks

  • Application developers write the code and the Tuxedo ATMI servers invoke the tpsvrinit() function only when the Tuxedo server is booted. Programmers use this function to open an application resource (such as a database) for later use.
  • Application developers write the code and the Tuxedo ATMI servers invoke the tpsvrdone() function only when the Tuxedo server is shut down. Programmers use this function to close any application resources opened by tpsvrinit().
  • Application developers write the code and the Tuxedo ATMI servers request named application services that process client requests. Tuxedo ATMI clients do not call servers by name; they call services. A Tuxedo ATMI client does not "know" the location of the server processing its request.
  • ATMI servers call the tpreturn() function to end a service request and return a buffer, if required, to the calling client.

tuxedo_server.gif

Figure 3: Tasks Performed by a Server

2.3. Using Typed Buffers in Your Application

All communication in the Tuxedo system is transmitted through typed buffers. The Tuxedo system offers application developers the choice of many different buffer types to facilitate this communication. All buffers passed through the Tuxedo system have special headers, and must be allocated and freed through the Tuxedo ATMI (tpalloc(), tprealloc(), and tpfree()).

tuxedo_buffers.gif

Figure 4: Different Types of Buffers

2.4. Communication models

The Tuxedo ATMI offers several communication models that you can use in your application:

  • Using the Request/Response Model (Synchronous Calls)
  • Using the Request/Response Model (Asynchronous Calls)
  • Using Nested Calls
  • Using Forwarded Calls
  • Using Conversational Communication
  • Using Unsolicited Notification
  • Using Event-based Communication
  • Using Queue-based Communication
  • Using Transactions

tuxedo_syncall.gif

Figure 5: Using the Request/Response Model (Synchronous Calls)

tuxedo_asyncall.gif

Figure 6: Using the Request/Response Model (Asynchronous Calls)

tuxedo_nestcall.gif

Figure 7: Using Nested Calls

tuxedo_forwcall.gif

Figure 8: Using Forwarded Calls

tuxedo_converse.gif

Figure 9: Using Conversational Communication

tuxedo_unsol.gif

Figure 10: Using Unsolicited Notification

tuxedo_eventbr.gif

Figure 11: Using Event-based Communication

tuxedo_qbased.gif

Figure 12: Using Queue Forwarding for Queue-based Service Invocation

tuxedo_trans.gif

Figure 13: Using Transactions

2.5. Example: simpapp

simpapp is a sample ATMI application that includes one client and one server. This application is distributed with the Tuxedo software. The server performs only one service: it accepts a lowercase alphabetic string from the client and returns the same string in uppercase.

The source code for the client program:

/* file simpcl.c (client)
   compile it by:
   buildclient -o simpcl -f simpcl.c
*/
#include <stdio.h>
#include "atmi.h"            /* TUXEDO Header File */

main(int argc, char *argv[])
{

         char *sendbuf, *rcvbuf;
         int sendlen, rcvlen;
         int ret;

         if(argc != 2) {
                  fprintf(stderr, "Usage: simpcl string\n");
                  exit(1);
         }
         /* Attach to BEA TUXEDO as a Client Process */
         if (tpinit((TPINIT *) NULL) == -1) {
                  fprintf(stderr, "Tpinit failed\n");
                  exit(1);
         }
         sendlen = strlen(argv[1]);
         if((sendbuf = (char *)tpalloc("STRING", NULL, sendlen+1))== NULL){
                  fprintf(stderr,"Error allocating send buffer\n");
                  tpterm();
                  exit(1);
         }
         if((rcvbuf = (char *)tpalloc("STRING", NULL, sendlen+1))== NULL){
                  fprintf(stderr,"Error allocating receive buffer\n");
                  tpfree(sendbuf);
                  tpterm();
                  exit(1);
         }
         strcpy(sendbuf, argv[1]);
         ret = tpcall("TOUPPER", sendbuf, NULL, &rcvbuf, &rcvlen, 0);
         if(ret == -1) {
                  fprintf(stderr, "Can't send request to service TOUPPER\n");
                  fprintf(stderr, "Tperrno = %d, %s\n", tperrno,
                            tmemsgs[tperrno]);
                  tpfree(sendbuf);
                  tpfree(rcvbuf);
                  tpterm();
                  exit(1);
         }
         printf("Returned string is: %s\n", rcvbuf);

         /* Free Buffers & Detach from TUXEDO */
         tpfree(sendbuf);
         tpfree(rcvbuf);
         tpterm();
}

The source code for the server program.

/* file simpserv.c (server)
   compile it by:
   buildserver -o simpserv -f simpserv.c -s TOUPPER
*/
#include <stdio.h>
#include <ctype.h>
#include <atmi.h>       /* TUXEDO Header File */
#include <userlog.h>    /* TUXEDO Header File */

/* tpsvrinit is executed when a server is booted, before it begins
   processing requests.  It is not necessary to have this function.
   Also available is tpsvrdone (not used in this example), which is
   called at server shutdown time.
*/
int
tpsvrinit(int argc, char *argv[])
{
       /* userlog writes to the central TUXEDO message log */
       userlog("Welcome to the simple server");
       return(0);
}

/* This function performs the actual service requested by the client.
   Its argument is a structure containing, among other things, a pointer
   to the data buffer, and the length of the data buffer.
*/
void
TOUPPER(TPSVCINFO *rqst)
{
      int i;

      for(i = 0; i < rqst->len-1; i++)
          rqst->data[i] = toupper(rqst->data[i]);
      /* Return the transformed buffer to the requestor. */
      tpreturn(TPSUCCESS, 0, rqst->data, 0L, 0);
}

Please reference: “$TUXDIR/samples/atmi/simpapp/”

Author: cig01

Created: <2013-03-16 Sat>

Last updated: <2016-10-26 Wed>

Creator: Emacs 27.1 (Org mode 9.4)