Object-oriented method and apparatus for information delivery6173327Abstract An object-oriented method and apparatus for delivering information from one component to another across a network of computers includes the steps of loading implementation libraries for adapter and information provider components into memory and creating factory objects for those components. When a request arrives over the network, the factory objects are called and stream objects are created by the factory objects. Data is then streamed from an information provider source to the original requester using the stream objects. Claims What is claimed is: Description BACKGROUND OF THE INVENTION
void Create ( in String path,
in unsigned long factoryType,
inout unsigned long contextBuffer,
out unsigned long streamType,
out Stream streamObject,
out unsigned long streamHandle
)
raises (Exception);
The first parameter, path, is the name of the resource for which a stream of information needs to be created. The second parameter is a factory type parameter that contains values indicating that the factory operation needs to find a resource and create a stream for that resource. The contextBuffer parameter contains the "Context" for the stream requested and can contain data that may cause the factory to behave differently. For instance, the context may include a request for data of a particular type (.JPEG, .GIF, e.g.). (A preferred configuration for the propagation of context is discussed below). The Create operation has three output parameters. A streamType parameter indicates the direction of the stream for the returned Stream object. The streamType parameter can have three possible values indicating whether the stream is for a "Get" operation only, for a "Put" operation only, or whether both operations can be performed. Each of these operations is discussed in detail below. The streamObject parameter contains an object reference for the requested Stream object. All subsequent stream operations must be addressed to this object. The streamHandle parameter identifies the stream of information within the Stream object. The streamHandle is provided to the Stream object to obtain information from the object. The Factory interface raises only one exception if an error occurs. In the preferred embodiment, an exception is raised for one or more of the following reasons: (1) the stream table is full; (2) the process does not have access to the required information for security reasons; (3) the requested resource does not exist; (4) the requested resource is not available (due to a locked file or a failed remote host, e.g.); (5) the requested resource is not available in one of the requested formats (the file is a .JPEG file and the caller specified that it would only accept .GIF files, e.g.); and (5) the operation was successful but no data is present. The Stream interface supports the streaming of information from one component to another component. Object calls are limited to a certain size depending upon the underlying mechanism used and its implementation on a specific system. The Stream interface facilitates the retrieval of information significantly larger than normal through multiple calls to an object's "Get" operation, as described below. A Stream object is called by other objects to obtain discrete units of information. The Stream interface contains four operations: Get, Put, Destroy, and Cancel. The Get operation is defined in IDL as follows:
void Get ( inout unsigned long opID,
in unsigned long handle,
inout unsigned long offset,
in unsigned long length,
out unsigned long buffer,
out boolean endofStream,
)
raises (Exception);
The Get operation is used by a component to read data from a Stream object ("stream" or "data stream") identified by a "handle." Data can be read sequentially or randomly. The Get operation takes handle, length, buffer, end of stream, operation identifier and offset parameters. The handle parameter identifies the requested stream of information. The handle for a stream of data is returned from the call to the Create operation on a Factory object. A length parameter specifies the amount of data the calling component is willing to accept. The maximum value allowed for the length is defined by the transport mechanism used for the object call. The actual amount of data returned may be less depending upon the implementation. The buffer parameter contains the requested data upon a successful return from the operation. The end of stream parameter (usually a boolean) indicates whether more data exists within the requested stream. The offset parameter describes the start of the block of data that is to be read. This value can be a byte position (if the particular implementation supports random data access) or a value that indicates that the data block starts right after the previous data block read from the stream. The operation identifier simply identifies the read operation. The Put operation is called to write data to the stream identified by the handle. Data can be written sequentially or, if the implementation permits, in random order. The Put method is defined as follows:
void Put ( inout unsigned long opID,
in unsigned long handle,
in unsigned long offset,
in unsigned long buffer
)
raises (Exception);
As the definition shows, the Put operation takes four parameters. The parameters are similar to their counterparts in the Get method, except these parameters correspond to a write operation. The Destroy operation is called when the stream identified by the stream handle is no longer needed. The Destroy method is defined as follows:
void Destroy (inout unsigned long opID,
in unsigned long handle,
in unsigned long dispose
)
raises (Exception);
The Destroy operation takes only three parameters: the operation identifier, the stream handle, and a dispose parameter that indicates how the stream should be disposed. In a preferred embodiment, the dispose parameter has three possible values indicating that the streaming completed successfully, the streaming completed unsuccessfully, or the streaming did not complete successfully because of an exception that occurred. The Cancel method is used to cancel an outstanding stream operation. The method is defined as follows:
void Cancel ( in unsigned long handle,
in unsigned long opID
)
raises (Exception);
The Cancel method takes only two parameters: the handle to the stream and the operation identifier. The Stream interface raises only one exception if an error occurs. The exception returns information regarding the streaming operation. In the preferred embodiment, exception information is returned for one or more of the following reasons: (1) the object that received the object call has no stream with the requested handle; (2) the stream has lost access to the data that was streaming due to a closed connection, file deletion or similar event; (3) a specific offset was out of bounds (larger than the file size); (4) a specific offset was out of reach for the stream implementation (Get method); (5) a "Get" method was performed on a stream object that should be written or a "Put" method was attempted on a stream object that should be retrieved; (6) a stream operation failed because of a time-out that occurred while an I/O operation occurred on behalf of the operation; and (7) Get or Put operation was performed requesting or supplying more data than the stream implementation can provide. V. Context As stated above, the components used by the present invention are configured as Implementation Libraries that can be loaded at different times. This configuration facilitates the creation of new components and allows the default functionality of each component to be easily changed. In order for each component to perform its function, however, each component may require specialized information to carry out its task. The present invention uses a Context structure to permit the run-time transfer of predefined information ("context") between components. In a preferred embodiment, context is passed from component to component using the context structure shown in FIG. 4. The structure is an octet string consisting of name/value pairs, where the name is an alphanumeric string and the value 197 is an any type defined in IDL. In addition, the string contains the length 191 of the context element, the length 193 of the entire string, and the length 195 of the name. The value 197 is an "any" type as defined in IDL and encoded using the Presentation Conversion Utilities ("PCU"). A PCU encoding is a presentation-independent encoding of an IDL-defined data structure. The Presentation Conversion Utilities are disclosed in U.S. Pat. No. 5,860,072. Context is implemented in the present invention as an abstract data type containing a variable amount of data. A component creates context and places information placed in the context structure, such as particular information about the component. The information is provided as part of the factory. The factory is then completed with context and shipped to the navigator. The navigator's decision is based solely on the context information. The information provider may or may not use the information provided in the context. If trading is involved, the trader uses the information. To manipulate and extend the context, a series of CEE routines are provided. These routines allow the structure of context to change without affecting the applications that utilize the context. Many of these routines take a pointer to a context buffer. The Put functions take a name and a descriptor of a data structure as written in compact IDL notation ("CIN"). CIN is described fully in U.S. application Ser. No. 08/680,270. A context structure is initialized by a component using the function IM_Context_Initialize, whose prototype is as follows:
IM_Context_Initialize (
in char *context,
in long size);
The context parameter is an allocated context structure as described above. The size parameter is the buffer space available in the context structure. This function initializes the context structure, preparing it for use by other functions. To store an element into a context structure, the component can call the function IM_Context_ElementPut, which returns a value IM_Context_RSXXX:
IM_Context_RSXXX
IM_Context_ElementPut (
in char *context,
in long contextSize,
in const char *name,
in const char *cin,
in void *buffer);
The context parameter contains an initialized context structure. The size of the context structure is specified in contextSize. The name of the element to be stored is specified by the name parameter. The cin parameter is a string describing the data type of the value of the element. The buffer contains the element's value that will be stored upon a successful return from the function. This buffer has the structure of an IDL "any" type. The function also returns information regarding the success or failure of the operation. The IM_Context_RSXXX value indicates whether or not the operation succeeded. If the operation did not succeed, the return value indicates that (1) an element with the name supplied was not found in the context; (2) the context supplied did not contain a valid context structure; or (3) the context supplied did not have room to store the element. Three functions, IM_Context_StringPut and IM_Context_LongPut are used to store a string or a long, respectively, into a context structure. These functions are defined as follows:
IM_Context_RSXXX
IM_Context_StringPut (
in char *context,
in long contextSize,
in const char *name,
in char stringValue);
IM_Context_RSXXX
IM_Context_StringPut (
in char *context,
in long contextSize,
in const char *name,
in char longValue);
In these functions, the context parameter is an initialized context structure. The size of the structure is specified by the contextSize parameter. The name of the string or long to be stored is specified by the name parameter and the value of the string or long to be stored upon a successful return from the function is specified by stringValue or longValue. The function returns IM_ContextXXX to indicate the success or failure of the operation. The return value, IM_Context_RSXXX, is identical to the return values for IM_Context_ElementPut. To retrieve elements from the context structure, the application or component can call IM_Context_ElementGet, IM_Context_StringGet, or IM_ContextLongGet, which are defined as follows:
IM_Context_RSXXX
IM_Context_ElementGet (
in const char *context,
in const char *name,
out any *buffer,
in long bufferSize,
out long *bufferUsed);
IM_Context_RSXXX
IM_Context_StringGet (
in const char *context,
in const char *name,
out char stringValue,
in long stringSize);
IM_Context_RSXXX
IM_Context_LonggGet (
in const char *context,
in const char *name,
out long *longValue);
The parameters are similar to their Get counterparts. The name parameter is the name of the string or long or element to be retrieved from the context structure. Elements can also be deleted from the context structure through IM_Context_ElementDelete, which is defined as follows:
IM_Context_RSXXX
IM_Context_ElementDelete (
in char *context,
in const char *name);
In this function, context is an initialized context structure and name is the name of the element to be deleted. The return value for each of these operations, IM_Context_RSXXX, is identical to the previous context functions. VI. Abstractions A. Adapter Each abstraction--Adapter, Gateway, Server, or Trader--is composed of one or more actual components. The Adapter abstraction waits for incoming requests from a requestor (such as a request from the Web Browser 49 on the client computer). The Adapter components connect information in the information delivery system to the requestor. As shown in the example of FIG. 6, an Adapter may include up to six components: (1) A transporter component; (2) an authenticator component; (3) a dispatcher component; (4) an adapter component (not to be confused with the Adapter abstraction); (5) a navigator component; and (6) a transformer component. The transporter component provides a requestor with an interface to various transport protocols on different platforms. The transporter component implements TransportFactory and TransportStream interfaces that inherit from the Factory and Stream interfaces, respectively. The TransportFactory creates a TransportStream object. The TransportStream object represents the resources necessary to establish a connection for a request arriving at the transporter component. The TransportStream interface supports the Get and Put operations. The Get and Put operations may correspond to reading and writing data or sending and receiving data. The TransportStream interface adds three additional operations: (1) Connect; (2) Accept; and (3) Disconnect. The Connect operation is called by a component to connect a TransportStream object to a remote host and is defined as follows:
void Connect (inout unsigned long opID,
in unsigned long handle,
in String path
)
raises (Exception);
The handle is the handle to the TransportStream object. The path parameter is a string that describes the connection to be made ("remote.host.com:80" for a TCP transporter or "//remote_host/pipe/named_pipe" for a Lan manager, e.g.). The Accept operation causes the stream to wait for new connections. When a connection is established, the call completes. The Accept operation is defined as follows:
void Accept( inout unsigned long opID,
in unsigned long handle,
out String path)
)
raises (Exception);
The handle parameter is the handle for a particular TransportStream object, as returned by the TransportFactory Create call. The path parameter is a string that describes the connection established. The Disconnect method causes the TransportStream object to disconnect from any remote host to which it is connected. The Disconnect method is defined as follows:
void Disconnect ( inout unsigned long opID,
in unsigned long handle
)
raises (Exception);
The authenticator component authenticates an information request that arrives at an Adapter abstraction. If the request contains user and password information, the authenticator can check the provided information against the operating system to ensure that the combination is valid. The dispatcher component of the Adapter abstraction is an Implementation Library that directs the processing of a request by dispatching the request to the proper Adapter components in the proper order. In a preferred embodiment, the dispatcher is code that runs a multithreaded statemachine. The dispatcher calls several Create operations for the Factory interfaces of various Adapter components. The dispatcher calls the navigator component to determine which information provider factory object to use for a request. The dispatcher invokes the information provider factory object. The dispatcher then streams data from the information provider stream into the transporter stream until the information provider stream indicates that no more data is available. The Adapter abstraction includes an adapter component that provides the logic for accepting a request and translating the request into a canonical form for use by other components. This component also provides the logic for returning a reply to the requestor. The adapter component uses a Translator library to convert requests and replies between a particular protocol and context. The Translator library contains functions to parse and generate requests and replies. The adapter component makes a parse request to the Translator library. The parse request takes the request as it arrived, parses it and stores relevant values in the context (as discussed above). Similarly, a reply can be created by taking the context and producing a protocol-specific reply. The navigator component takes a canonical request (as provided by the adapter component) and decides what information provider and trader to use to fulfill the request. The navigator component implements a Navigator interface having a single Navigate operation, defined as follows:
void Navigate ( inout unsigned long contextbuffer,
out unsigned long factory reference,
out String factoryPath
)
raises (Exception);
The navigator provides navigation through an interface that takes a subject and a context as parameters. The navigator then modifies the context based upon navigation rules that are configured into the component. The rules used by the navigator are subdivided into subjects. A subject is used as a rule in a rule tree. The navigator's configuration can contain many subjects. Navigation based upon a single subject will add additional values to the context related to that particular subject. Navigation is based upon rules. A rule must contain a condition and can optionally contain an assignment and other rules. A condition consists of atomic conditions. Atomic conditions take one of the following forms: contextelementname--`regular expression`: This atomic condition yields true when the value of the context element indicated by contextelementname is of type string and matches the regular expression given by `regular expression`. contextelementname operator "string constant": This atomic condition yields true when the value of the context element indicated by contextelementname is of type string and compares to the string given by "string constant". Operator is one of "=", ">", "<", ">=", or "<=". contextelementname operator numeric constant: This condition yields true when the value of the context element indicated by contextelementname is of a numeric type and compares to the value given by numeric constant. Operator is one of "=", ">", "<", ">=", or "<=". In addition, atomic conditions may be combined to yield more complex conditions through the operators "not", "and," and "or". The transformer component transforms data from one format to another. The transformer can be positioned between a dispatcher component and an information provider. The transformer will appear to be an information provider to the dispatcher component and will appear to be a dispatcher component to the information provider. Thus, transformation is performed transparently to the various components. A transformer utilizes the Stream and Factory interfaces. The transformer Factory object calls an information provider Factory object to manufacture an information stream. The transformer Factory then manufactures a transformer Stream object and attaches the information stream and a transformation function. The factory returns the transformer Stream object's reference and handle. Exceptions can be returned indicating the success or failure of the operation. FIG. 6 shows the components of a sample HTTP Adapter. The HTTP adapter includes a TCP transporter component 155 that provides common interfaces to TCP across all platforms. The TCP Transporter factory creates a socket and optionally binds the socket to a port. The TCP Transporter Stream uses the Accept operation to listen and accept socket calls on the port. When a request arrives, the Accept call completes. The Connect operation is used to perform a connect socket call. The TCP Transporter stream can then use the Get operation to perform a receive on the socket. The Put operation is used to perform a send on the socket. An authenticator component 161 authenticates a request for information that arrives at the adapter from an application. The authenticator component can be utilized to check for password and other user-specific information. This information is checked against the operating system. The dispatcher dispatches the request to the remaining components in the Adapter. A transformer component 157 produces Hypertext Markup Language ("HTML") from different types of textual information. The adapter component 153 uses the TCP transport to accept HTTP requests and write their replies back over the network. The adapter uses a Translator library containing functions to parse and generate HTTP requests and replies. The adapter makes a parse request that takes the HTTP request header and stores it into context elements. A navigator component 159 decides, based upon certain configuration information, what information provider or trader should be used to fulfill the request. The functioning of each of these components will be described in detail below following the description of the interfaces implemented by each component. B. Trader The trader 150 includes only one component, termed the trader component which implements Trader Factory and Trader Registration interfaces. The dispatcher component of the Adapter calls the trader's Factory object. The trader component uses a load-balancing algorithm to select one information provider out of the many running instances of information providers. The trader returns a valid stream object reference and handle for an Information Provider. At start-up, information providers register with the trader and inform the trader of their capabilities for delivering information. When the Create operation is called on a trader Factory object by the dispatcher, the trader selects an Information Provider Factory object. The trader calls the factory object for the Information Provider and returns the stream object reference and stream handle to the dispatcher. The trader can return an exception if no information provider factory object of the requested type has registered with the trader or if all available information provider factory objects are busy. The Trader Registration interface allows information providers to register with the trader. The trader can then select an information provider based upon the information provided to the trader by the dispatcher component of the Adapter. The Trader Registration interface includes a Register New Information Provider operation, an Un-register Information Provider operation, and a Change Registration Information operation. The Register New Information Provider call is used by information providers to register themselves for trading. Each information provider supplies its name (e.g., "File Server, "Gopher Gateway", etc . . . ), its object reference, the maximum number of streams that its factory is configured to create, and any other information that can assist the trader in performing a load-balancing algorithm. The information provider calls the Un-register Information Provider to indicate that the information provider will shutdown or otherwise become unavailable for trading. The Change Registration Information Provider call is used to change the number of streams that a registered information provider can create or another property that affects trading. If the trader component receives an exception upon calling an information provider factory object, the trader has the possibility to recover from the failing factory. When more than one information provider factory object is available and an exception is returned for one of the factory objects, another factory object may be used. When only one information provider factory object is available and an exception indicates that the factory is temporary, the trader can be configured to wait a predetermined amount of time and retry invoking the factory object. C. Information Provider 1. Gateways A Gateway Abstraction is used to connect external information to the Information Matrix. The Gateway includes a transporter component and a gateway component. The transporter component performs the same function as the transporter component used in the Adapter abstraction. Thus, the transporter component provides an abstraction for the various possible transport protocols and the different interfaces to the protocols on different platforms. The gateway component registers itself with the trader at start-up. The gateway component then provides the logic for taking a request in the canonical form (as created by the adapter component) and translating the request into an external request that can be sent out over a network using the transporter component. The gateway component also provides the logic for accepting a reply from a remote host. The gateway component implements Factory and Stream interfaces. The Factory interface contains only a Create operation. When called, a gateway Factory object creates a Stream object and stream context. The stream context can contain, depending upon its implementation, file handles, SQL cursors, additional object references, etc . . . The Stream interface uses the Get, Put, and Destroy operations. The Get operation is used to request a certain range of bytes from a stream. The Put operation stores a certain range of bytes in a stream. The Destroy operation tells a Stream object that the object will no longer be used. The Stream object frees its resources and the object may be deleted. In a preferred embodiment, a stream is identified by a Stream object reference and a stream identifier. The stream identifiers are assigned by the gateway stream Factory when a call is made to the Factory. A stream identifier is a handle to an entry in a stream table. The stream table is used as a lookup table to determine the data that must be provided. The stream table contains a streams context that can be different for each implementation of a gateway. Thus, the stream context can contain file handles, socket numbers, object references, SQL cursors, or any other context that must be maintained between different calls to a Stream object. FIG. 7 shows a sample gopher gateway 139. The gateway 139 includes a gateway component 169 and a TCP transporter component 171. The gopher gateway 139 uses the same TCP transporter 171 as used in the HTTP adapter. The gopher gateway component 169 uses the TCP transporter component 171 to send gopher requests and receive replies back over the network. 2. Servers A Server abstraction contains only a server component. The server component accepts a canonical request (as created by the adapter component) and resolves the request by accessing local information. The server implements a Factory and a Stream interface. The Create operation on a server Factory object attempts to open the requested file. If the file is successfully opened, the Factory creates a Stream object is created and initializes an entry in the stream table. The stream table contains the file name, file handle, file size, and number of bytes written and read after each operation. The Get operation on a Stream object performs a read on the opened file. The Put operation writes to the opened file. The Destroy operation closes the file and deletes the entry in the stream table. VII. System-Level Interactions Between Components A. Non-trading Interactions Referring now to FIG. 8, a macroscopic view of the interaction between the various components using the above-described interfaces will be described. A more detailed description of each component's implementations is described later. All interactions between the components are based on object calls. The object calls function transparently between objects in the same capsule, between objects in different capsules and between objects on different machines. Each of the FIGS. 8-13 shows object creation and interaction over a period of time (progressing from top to bottom). In particular, a start-up phase, set-up phase, stream phase, and clean-up phase are shown. Each component (or "Implementation Library" or "IL") is depicted as a box containing one or more additional boxes that represent interfaces. Object creation and destruction is denoted by a hollow circle. The life of the object is denoted by a vertical line extending from the object. An arrow with a hollow point represents object interaction. An arrow with a filled point represents object interaction that includes the passing of a context structure. Adapters 131, 133, 135 and Information Providers 137, 139, 141, 143 may interact with or without the Trader 150. In most circumstances, a trader 150 is involved. If, however, the information delivery system includes only a single server providing a single purpose, the trader is not necessary. First, with reference to FIGS. 8, 9, and 10, interaction without the trader 150 will be described. This discussion assumes that a request from the WWW browser 49 arrives at the HTTP adapter 131 as shown in FIG. 6 and that the gopher gateway 139, as shown in FIG. 7, will be used as an information provider. It should be apparent, however, that a request may arrive at other adapters, such as a gopher adapter or NNTP adapter, for example. Further, a gopher gateway or FTP gateway or local file server may be used as an information provider. FIG. 8 shows the streaming of data between components during start-up, set-up, stream, and clean-up phases. As stated above, the components of each abstraction, preferably, are loaded in a separate capsule. In this FIG. 8, Adapter components, including an adapter component 153, a dispatcher component, and a navigator component 159 is loaded in an Adapter capsule. An information provider component 139 is loaded in an Information Provider capsule. During the start-up phase, the various components are initialized and loaded. In step 803, the implementation libraries are loaded and their initialization routines are called. The initialization routines for an adapter component and information provider component cause a Factory object 1530, 1390 to be created. The navigator component 159 causes a Navigation object 1590 to be created. In step 805, the dispatcher component 151 creates a context structure and calls the Create operation on the adapter 153 Factory object with the context structure as a parameter. When an external request arrives at the adapter 131, from the WWW browser 49 on the client computer 40 or elsewhere, the Create operation will be completed, resulting in an adapter Stream object. Following this initial start-up phase, the set-up phase begins. The IM computer 60 processes requests that arrive at the adapter 131. In step 807, a request from the WWW browser 49 loaded in the client computer 40 arrives at the adapter 131. The adapter 153 factory, in step 809, creates an adapter Stream object 1531 for the request. The Stream object 1531 is an interface to the web browser 49. Next, in step 811, the adapter 153 replies to the Create call from step 805. The reply to the Create call contains a reference to the newly created Stream object 1531 as well as a stream handle and all details of the request are contained in the context buffer. In step 813, the dispatcher component 151 calls the navigator component 159 with the request context created by the Create call from step 805. The navigator 159 uses the request context to select an information provider Factory object that can create a Stream object to satisfy the external request. In step 815, the navigator 159 replies to the dispatcher 151 with a reference to the selected information provider Factory object 1390. The dispatcher 151 then calls the information provider Factory object 1390 to obtain a Stream object for the requested information. In step 819, the information provider Factory object 1390 accesses the requested information. Next, in step 821, the information provider Factory manufactures a Stream object 1391 for the information. Finally, in step 823, the information provider Factory object 1390 returns a reference to the created information provider Stream object 1391 to the dispatcher 151. During the stream phase, objects and components stream data to each other. Streaming can occur in both directions between information provider and requester. The stream phase shown in FIG. 8 describes the retrieval of information from an information provider to a requester. The storage of data in an information provider is similar to the case of retrieval except the data flows in the opposite direction. In step 825, the dispatcher 151 calls the information provider Stream object 1391 using the Get operation to obtain a block of data from the stream. The information provider 139, in step 827, accesses the external information source (or local information source, in the case of a server) to obtain a piece of data of the size requested. Next, in step 829, the information provider stream object 1391 returns the piece of data and a value (usually a boolean) that indicates whether there is more data available from the stream. The dispatcher 151 calls the adapter Stream object 1531 using the Put operation supplying the data returned by the information provider stream. In step 833, the Adapter returns the requested information to the external requestor (the WWW browser 49). In step 835, the adapter returns the Put call made in step 831. When streaming is completed, as indicated by the information provider stream returning from a completed Get operation, the streams are destroyed. In step 837, the dispatcher 151 calls the Destroy operation of the information provider Stream object 1391. In step 839, the information provider returns the call. Next, in step 841, the information provider Stream object 1391 destroys itself after closing and freeing all resources acquired for the stream. The dispatcher 151, in step 843, calls the Destroy operation of the adapter Stream object 1531. In step 845, the adapter Stream object 1531 returns the call. Finally, in step 847, the adapter stream object 1531 destroys itself after closing and freeing all resources acquired for the stream object. B. Interaction with Trader Now, with reference to FIG. 9, component interaction with the trader component 150 will be described. The start-up phase is similar to the start-up phase in the non-trader context, except that the information provider factory object 1390 registers itself with the trader object 1500 at start-up. In step 907, a request from the WWW browser 49 arrives at the HTTP adapter 131. In step 909, the adapter 153 creates a Stream object 1531 for the request that acts as an interface to the web browser 49. The adapter 153, in step 911, completes the factory operation by replying to the factory call from the start-up phase. The reply contains a reference to the created Stream object 1531 and also contains details about the request in a request context. The dispatcher 151, in step 913, calls the navigator 159 with the request context created in the start-up phase. The navigator 159, based upon the rules discussed above, uses the context to select a trader object 1500 capable of creating a stream to satisfy the external request. (If a single trader 150 is used, the navigator 159 selects the single trader.) In step 915, the navigator 159 replies with an object reference to the selected trader object 150. The dispatcher 151 then calls the trader object 1500 to obtain an information provider Stream object for the requested information The trader object 1500, in step 919, selects an information provider Factory object 1390 and calls the object. The Factory object 1390 is selected based upon a load-balancing algorithm. The information provider Factory object 1390 accesses the requested information in step 921 and manufactures a Stream object 1391 for the requested information in step 923. Next, the information provider Factory object 1390 returns the call with a reference to the created Stream object 1391. The trader object 1500, in step 927, returns the reference for the information provider stream object 1391 to the dispatcher. Streaming of data and clean-up is similar to the non-trading scenario. The trader 150 is transparent to the non-navigator components. VIII. Abstraction-level Interaction Between Components As stated above, each abstraction may carry out the above operations as required for a particular developer's needs. An Adapter abstraction, for example, may or may not include an authenticator. Accordingly, each abstraction may have a different internal structure. Now, with reference to FIGS. 10-13, preferred interaction between components within an abstraction will be discussed. A. Adapters FIGS. 10a-10b shows the interaction between Adapter components. In step 1003, the initialization routines of the authenticator 161 and navigator 159 create objects 1610, 1590 to satisfy requests. The transporter 155 and the adapter 53 create Factory objects 1550, 1530. In step 1005, the dispatcher 151 calls the Factory object 1530 created by the adapter 153. (The dispatcher may call the Factory object many times depending upon the number of requests that the dispatcher is willing to serve. For this example, we assume that only one request can be handled.) In step 1007, the adapter, upon receiving the call to the Factory object, calls the transporter Factory object 1550. The transporter Factory object 1550, in step 1009, creates a transporter Stream object 1551. The transporter Factory object 1551 returns the transporter Stream object reference and handle to the adapter 153 in step 1011. The adapter 151, in step 1013, calls the transporter Stream object's Accept operation. The Accept operation, as discussed above, causes the transporter stream object 1551 to wait for incoming requests. The set-up phase begins at step 1015. In step 1015, a connect request from the web browser 49 arrives at the Adapter over the network. Specifically, the request arrives at the transporter component 155 causing the transporter stream object 1551, in step 1017, to return the outstanding Accept call. The adapter Factory object 1530, in step 1019, calls the transporter Stream object 1551 to read the incoming request in step 1021. In step 1023, the transporter Stream object 1551 returns the data to the adapter Factory object 1530. The adapter Factory object 1530, in step 1025, parses the request. If the request contains user information, this user information is validated by the authenticator in step 1027. In step 1029, the adapter Factory object 1530 creates an adapter Stream object 1531. The adapter Stream object 1531 has a context component that includes the transporter Stream object reference and handle. In step 1031, the adapter Factory object 1530 returns the Create call from step 1005 by returning the adapter Stream object reference and handle to the dispatcher 151. The dispatcher 151, in step 1033, calls the navigator 159 to find an information provider for the request. The navigator 159, in step 1035, returns a reference to an information provider object if a trader is not used. If a trader is used, the navigator 159 returns a trader object reference. The navigator may also return a transformer object reference. The dispatcher 151, in step 1037, calls the information provider Factory object (not shown) to manufacture a Stream object. The information provider returns a Stream object and handle in step 1039. FIG. 10b shows the stream phase and clean-up phase for an Adapter abstraction. In step 1041, the dispatcher 151 calls the Get operation on the information provider Stream object to obtain a block of data. The information provider Stream object returns the block of data in step 1043. In step 1045, the dispatcher 151 writes the retrieved data to the adapter stream object 1531 using the Put operation. In step 1047, the adapter Stream object 1531 writes the data to the transporter Stream object 1551 using the Put operation. The transporter Stream object 1551 writes the data over the network to the web browser 49 in step 1049. In steps 1049 and 1051, the transporter Stream object 1551 and adapter Stream object 1531 return their respective Put operations. The process of continuously calling the Get operation on the information provider stream object and the Put operation on the adapter and transporter stream objects continues until the information provider stream object returns an end-of-stream indication to the dispatcher 151. In step 1053, the dispatcher 151 calls the information provider Stream object using the Destroy operation. The information provider Stream object, in step 1055, returns the call and destroys itself. In step 1057, the dispatcher 51 calls the adapter Stream object using the Destroy operation. The adapter Stream object 1531, in turn, calls the transporter stream object's Destroy method in step 1059. The transporter Stream object 1551, in step 1061, ends the request by closing the network connection. In step 1063, the transporter Stream object 1551 completes the call from step 1059 and destroys itself in step 1065. The adapter Stream object 1531, in step 1067, completes the call from step 1057 and destroys itself in step 1069. The dispatcher recalls the adapter Factory object 1530 in step 1071 to obtain the next incoming request. In step 1073, the adapter 153 calls the transporter Factory object. The transporter Factory object creates a transporter Stream object 1552 in step 1075. In step 1077, the transporter Factory object returns the created Stream object reference and handle to the adapter 53. The adapter 153, in step 1079, calls the transporter Stream object's Accept operation. The transporter 55 is then ready to accept another request. When a new request arrives, the adapter enters the set-up phase once again. B. Traders As discussed above, a Trader includes only a trader component implementing a Trader Factory and Trader Registration interface. The trader component implements these interfaces as shown in FIG. 11. During the set-up phase, a factory request arrives at the trader 150, and the trader selects an instance of a particular class of information providers that can fulfill the request. The trader, in step 1105, then calls the information provider Factory to manufacture an information provider Stream object. The information provider creates a Stream object 1391 in step 1107. Next, in step 1109, the information provider returns the information provider Stream object reference and stream identifier to the trader. The trader returns the information provider stream to the caller--the dispatcher--in step 1111. During the stream phase, the dispatcher continues to stream from the information provider stream without being aware of the intermediacy of the trader. When the information provider finishes streaming, in step 1115, it sends an end-of-stream indication. During clean-up, the dispatcher destroys the manufactured stream. Clean-up occurs without the use of the trader 150. C. Information Providers FIG. 12 describes the information provider implementation of Factory and Stream interfaces using a stream table and an object table stored in memory 40. In the start-up phase, at step 1203, the initialization routines of the implementation libraries are called. This routine creates an information provider Factory object 1390. If the trader is being used, the information provider will register with the trader by calling the trader object using the Register New Information Provider operation. In step 1205, the information provider receives a factory call from the dispatcher or from the trader. In the implementation of the information provider Factory, information in the call is used to select an information source and verify that the source can access the information. In step 1208, the Factory implementation selects a stream table entry for a new stream. The implementation generates a new unique handle for the stream and writes the stream context into the table entry. Next, in step 1209, the Factory implementation creates or selects an addressable Stream object 1391. The Stream object reference and handle are returned to the caller in step 1211. In the stream phase, streaming can take place in two directions using the Get and Put operations. In step 1213, a stream call arrives at the Stream object via a Get or Put Call. The call contains the stream handle. The stream object 1391 validates the stream handle and uses the handle to access the entry in the stream table in step 1214. The information in the stream table is used, in step 1215, to access the data required to complete the call. In step 1217, the Stream object 1391 returns the call. In the clean-up phase, a Destroy call containing the stream handle arrives at the stream object 1391. In step 1220, the stream handle is validated and used to find the stream table entry. In step 1221, the information source is closed. In step 1223, the Destroy call completes, thus destroying the Stream object 1391 in step 1225 and freeing the stream table. D. Transformers Transformers may be used with Adapters and Gateways. Accordingly, streaming of data occurs differently if a transformer component is used. FIG. 13 shows the interactions to and from a transformer component. Initially, in step 1303, a transformer Factory object 1570 and information provider Factory object are created. Next, in step 1305, a factory call arrives at the transformer factory object 1570 from the adapter component 153. The transformer Factory object 1570 calls an information provider Factory object 1390 in step 1307. The information provider Factory object 1390 creates an information provider Stream object 1391 in step 1309. In step 1311, the information provider Factory object 1390 returns the newly created Stream object's reference to the transformer Factory object 1570. The transformer Factory object 1570, in step 1313, creates a transformer Stream object 1571 and keeps the information provider Stream object's reference as part of the transformer Stream object's context. The transformer Factory object 1570 returns the transformer Stream object reference and handle to its caller. In step 1317, a Get call arrives at the transformer's Stream object 1571. The transformer, in step 1319, calls the information provider stream object 1391 using a Get call to obtain data. The information provider Stream object 1391 returns data in step 1321. The transformer transforms this data using a transformation function. The transformation function examines the retrieve buffer for data to be transformed. If sufficient data to be transformed is contained in the buffer, the data is removed from the retrieve buffer, transformed and stored in the reply buffer. The Get call to the information provider is called again if the reply and retrieve buffer are not full and the information provider's stream object does not indicate "no more data". The transformer stream object's Get method returns the data from the reply buffer. The Stream object 1571 will indicate that "no more data" is available is there is not a "no more data" indication on the information provider's stream object, the retrieve buffer is empty, or the remainder of the reply buffer is returned. In step 1323, the data is returned to the dispatcher. If data were being stored, a Put call would arrive at the transformer in step 1317. The Put operation works similarly to the Get operation except information flows in the opposite direction. In the clean-up phase, the Destroy method arrives at the transformer Stream object 1571 in step 1325. The transformer 157 performs a Destroy call on the information provider's Stream object 1391 in step 1327. The information provider Stream object, in step 1329, returns the call. The information provider destroys the information provider Stream object 1391 in step 1331. The transformer stream object 1571 returns the call in step 1333. The transformer, in step 1335, destroys the Stream object 1571. Having thus described a preferred embodiment of an object-oriented method and apparatus for delivering information, it should be apparent to those skilled in the art that certain advantages of the within system have been achieved. It should also be appreciated that various modifications, adaptations, and alternative embodiments thereof may be made within the scope and spirit of the present invention. For example, the use of a single trader has been illustrated, but it should be apparent that the inventive concepts described above would be equally applicable to a multiple-trader scenario. Indeed, each component may be replicated to support numerous protocols and configurations. The invention is further defined by the following claims.
|
Same subclass Same class Consider this |
||||||||||
