ScopeThis document contains description of mapping of all Datatypes based model method invocations into Requests submitted to Abeans Engine for delivery to the plug. More specifically, this document determines the target part of the Request, i.e. the transformation of the method invocation in the URI that specifies the target uniquely. An additional form is defined as well, which can be used to "serialize" or "stringitize" the whole request: an XML form conformant to the SOAP specification. AudienceTHe intended audience are developers that maintain, use, or extend the Abeans Engine or Abeans plugs. Table of Contents1. Introduction2. Mapping Types2.1. Basic URI Mapping2.1.1. Scheme Part2.1.2. Authority Part2.1.3. Path Part2.1.4. Query Part2.1.5. Examples2.1.6. Application Dependence on Plugs2.2. XML SOAP Mapping3. Case-by-Case Request Specifications3.1. Dynamic Value Get Request3.2. Dynamic Value Set Request3.3. Dynamic Value Monitor Request3.4. Characteristic Read Request3.5. Dynamic Value History Request3.6. Grouped Characteristic Read Request3.7. Dynamic Value Asynchronous Get Request3.8. Dynamic Value Asynchronous Set RequestDocument History1. IntroductionIn Abeans Release 3, the data flow between the user of the framework and the underlying (possibly remote) system proceeds through Abeans Engine. Abeans Engine is an in-memory database that issues requests, processes them, forwards them to the plugs for execution on a specific communication system, receives the replies and forwards them to the user. In Release 3, Abeans support custom models, i.e. sets of interfaces that model or parametrize the sytem to which Abeans connect. Thus, for example, we know Channel model (where channel is defined as a dynamic value plus its characteristic context), BACI wide model etc. The user of the Abeans framework interacts directly with the model by invoking its methods. The model must communicate with Abeans Engine, ask it to issue requests, fill out the requests, submit them to the Abeans Engine database, wait for the replies and unpack them. The advantage of this approach is that all data flow must pass through Abeans Engine in the form of abeans.engine.Request and abeans.engine.Response instances. In this way, the data flow is well-defined and, moreover, additional processing can be done at the database layer, such as storing of reqeusts to permanent storage, indexing of requests, distributing reports for special requests or faulty responses and so on. To summarize: Abeans Engine narrows any kind of model down to the management of instances of two types, namely request and response, with fixed interfaces. In order to better understand the relationships between parts of Abeans introduced above, the following interaction diagram should be of some help. The user is represented as invoking a getValue operation on an interface of the Channel model. This operation requests the value of a remote property to be queried by getting a Request instance from the Abeans database, setting up the request, and submitting it to the database. Independently of the Channel model the database must now use its threading and other policies to forward the request to the plug (which executes it by sending it to the remote server) and obtain a response. The response is then synchronously (in this example case) returned to the calling Channel.
Figure 1: The connection between Datatypes-based model (like Channel) and Abeans Engine. Abeans put almost no restrictions on the nature of the model which communicates with the Engine and the interfaces that parametrize the model can take various forms. However, there is a subset of all models that we will discuss in this document, namely models that are based on the Cosylab Datatypes-Common project. Such models describe constructions known as properties, i.e. dynamic values (changeable value, like some physical parameter) in their characteristic contexts (static values describing the dynamic value, such as units, format, description etc). Usually, these models allow different kinds of accesses to dynamic value with regards to its Java type (e.g. access to dynamic value as double type, as int type etc.) or the access mode (synchronous access, asynchronous access, monitor access). Having so enumerated the capabilities of the Datatypes-Common based models, we can define the mapping of every possible access type in Datatypes-Common to a Request in the Abeans Enigne. Each Request submitted to the Abeans Engine database has a property known as target. This is a string uniquely identifying the data source in the controlled system and the action that should be performed on that source. For example, a target PBEND_M.01/curent/minimum?get is a fictional target, that could specify that an operation get is to be invoked on the data source PBEND_M.01/current/minimum. Such target string might be generated when the user of the framework called method getMinimum() on an instance of DoubleChannel that is connected to the data source with name PBEND_M.01/current. Abeans designs are based on the premise that regardless of the model interfaces, the mapping of the interfaces to such target strings is always possible. This document defines such mapping for all Datatypes-Common based models. 2. Mapping TypesTwo mappings of different types will be defined in this document. Firstly, a mapping of the all Datatypes-Common method invocations into target alone will be specified. The target in this case will follow the URI specifications of RFC 2396 and will be called simply "the mapping" or "basic mapping". The second mapping, called "XML mapping" or "SOAP mapping" will map a Request instance to an XML fragment, containing all data items needed to reconstruct from XML an identical request. The purpose of the fist mapping is to have a consistent way of exchanging data between Abeans Engine and the plugs. If we follow external standards, it will be easy to create a wide variety of applications, such as web pages with dynamic content that access values just by specifying full target URIs. The parsers for URIs are a part of the standard Java 1.4 platform, as well. XML mapping is designed for request storage on the permanent media or for Web applications that exchange data directly with Abeans running as a server platform. 2.1. Basic URI MappingURIs defined in this document follow the hierarchical URI syntax, defined as: [scheme:][//authority][path][?query][#fragment] The mapping of Datatypes-Common and Abeans concepts to these parts is defined below. 2.1.1. Scheme PartThe scheme contains a general keyword that identifies the following URI as a part of the Abeans system. The keyword is equal to the Java package prefix of the Abeans, namely "abeans". To this, we append a separator character "-". After the separator, we specify the name of the plug that will handle the request, for example "TINE". The scheme part is therefore composed of Abeans identifier and plug identifier, which is correct, since each pluggable system has a specific way of binding of names to remote data sources. 2.1.2. Authority PartAbeans interface abeans.models.Connectable parametrizes an entity that can be connected, i.e. that can have its string name resolved into the connection to the remote data source. This name resolution is performed within the scope of the name service offered by the underlying controlled system. There may be one such naming service (one well-defined namespace), zero such naming services (global namespace) or many naming services. If a naming service exists, the authority part must contain its unique identification. The interpretation of such identification is left to the plug. The identification, as per RFC, extends to the first slash '/' character after double slash '//' prefixing the authority part. For example, an authority might be a server name cheka.ijs.si:3000, where the naming service runs. If there are zero naming services, the authority part is empty, and the name is a global name. In this case, scheme is followed by a semicolon and triple slash '///'. 2.1.3. Path PartPath part does not depend on the pluggable system. It is composed of the name of the Connectable instance, which the authority part can resolve, and with path name that specifies the desired data source within that connectable. In Channel model, where Channels directly implement Connectable, the first part of the name is directly the channel name. In other models, where Datatypes-Common interfaces are not directly implemented by Connectable types (like in BACI, where a Device is a Connectable, but a Property only a Linkable), the first component of the name must be the device name. If no other path component is present after the name of the Datatypes-Common property, the target path formed by such URI represents directly the dynamic value of that property. If other path components are specified after the property name, they must be separated from the property name by URI hierarchy separators, namely slash '/' characters. Such further path components refer to data sources inside the property, which may be - as per Datatypes-Common specifications - characteristics or asynchronous mode invocations. A characteristic is a name-value pair. It can either be declared statically in the implementing class of Datatypes-Common interface as a JavaBeans property, or it may be dynamic, accessible during run-time through name-value lookup. In the first case the name of the characteristic is implied from the JavaBeans design pattern, where accessor methods conform to the prototype
In the second, dynamic case, the property names are defined as static final constants in either Datatypes-Common libraries, or, additionally, in their Abeans extensions in abeans.datatypes. When implementing a new model or a new plug, a characteristic name already defined must be used. Only if a name does not exist for the characteristics of a given function, may a new name be introduced. Asynchronous operations can be declared by types that implement the AsynchronousMode interface from the Datatypes-Common project. The method signature for the asynchronous operations is as follows:
In short, asynchronous operations return instances of their Request objects, which may be used to track the progress of the operation. The name of the asynchronous operation is simply its method name. In this way, both characteristic and asynchronous operation names are well defined. In conclusion, it is possible to form a unique name identifying either a characteristic or an asynchronous action, by suffixing it to the property name. 2.1.4. Query PartA query part provides parameters that further qualify the target, where this is needed. In Datatypes-Common compliant model implementations, such as BACI model or Channel model, the query is, in basic mapping, defined only for the target specifications that name the dynamic value directly. When this is the case, the following query parts are defined:
Table 1: Possible query strings when the target names the dynamic value. 2.1.5. ExamplesThis section provides some URIs in the simple mapping, which are constructed according to the guidelines described above. XML mapping will contain the URI mapping and, in addition, all the parameters that parametrize a Request. The reason in short is that in XML mapping, the XML must contain the complete request data (along with the expected timeouts, parameters, properties, blocking modes etc. as defined in the Request documentation), whereas in simple mapping all those additional data items are programatically present in the Request object. As an example, we will work with channel implementation of the Datatypes-Common model. In this implementation, Channel instances are Connectables and are top-level objects that can be resolved from string names. Let our channel name be PBEND_M_01_current. Let us also assume, that there is no name resolution authority, such as is the case with EPICS, and that the model is communicating through the plug named EPICS. Then abeans-EPICS:///PBEND_M_01_current?get will request the value of the channel to be read, whereas abeans-EPICS:///PBEND_M_01_current?set will generate a set request in the plug, and abeans-EPICS:///PBEND_M_01_current?monitor will start a new monitor on the dynamic value. In case of TINE, the situation is a bit different. TINE supports hierarchical naming and also has dedicated name servers. The syntax for reading the dynamic value then changes into: abeans-TINE://ns.desy.de/DESY/BENDS/PBEND_M_01/current?get In this case, the naming authority is specified and the path to the correct Channel ("current") is thorugh TINE Namespaces (i.e. context, server, device). To read a characteristic, its name is appended after the property (dynamic value) name, in the following manner: abeans-EPICS:///PBEND_M_01_current/minimum?get Query flags are not needed, since characteristics are only read. In the same way asynchronous operations can be executed, where the default operation on the asynchronous operation data source is its execution. 2.1.6. Application Dependence on PlugsIf URI strings like the above examples are hardcoded into applications, two problems may arise:
To address these issues, Abeans do not by default specify the targets by URIs, but through abeans.pluggable.RemoteInfo instances. These instances specify the plug type as a separate string field and do not specify the name authority. The plug type can be left unset, in which case it defaults to the single plug used by the application. If multiple plugs are used by the application and the plug type is not specified, this will cause an exception to be thrown. The same principle applies to the name authority. To summarize: the RemoteInfo contains, as its name field, only the path?query part of the full URI specification. Implementations of RemoteInfo interface must be able to generate the full form URIs according to the syntax presented here. The database and the plug, however, must be able to process full URI target specifications of the above format. With this approach, multi-plug, multi-name-authority applications are still possible, while simplicity is retained for single-plug, single-name-authority applications. Moreover, the URIs are not visible from the model layer at all, because they are handled internally by Abeans. Consequently the dependence of the application on the underlying pluggable system reduces to the dependence on the structure of the path component, which cannot be generalized. But even for this problem there exists a solution in terms of mapping tables, that exist in the plug. Two Channel applications running on different plugs, A and B, naturally differ in their channel names. However, if one of the plugs (say A) maps the names of plug B into its own names, the same applications can run without modification on different plugs. 2.2. XML SOAP Mapping3. Case-by-Case Request SpecificationsThis section defines request structures for different operations that are allowed within the Datatypes-Common framework and consequently within all Abeans models that are based on this framework. For each type of interaction of the model and the database, the request fields and their mandatory or optional values are presented here. 3.1. Dynamic Value Get RequestThe following table lists the request structure for the dynamic value get operation:
Table 2: Request structure for dynamic value get. When this request is received by the plug, the plug must immediately respond by calling back database with message requestStarted. When the return value is obtained from the remote layer, the plug must use the RequestResponseFactory interface to create a new Response, set the error and completion fields, leave the qualifier field empty, and insert a new value into the Response. The response must be of the ResponseType type. The plug finally performs Request.addResponse() to add a new response to the request and invokes requestNewResponse callback on the database. This finishes the processing of the request.
The model will submit this request as a RequestType.SINGLE_REQUEST, which means that the first response is also the last response and that the request automatically terminates when the first response is received. 3.2. Dynamic Value Set RequestThe request structure is the same as in Dynamic Value Get Request, but with the following differences:
Table 3: Request structure for dynamic value set. The plug confirms the request execution by submitting back an instance of Request with no value and calling back the database.
3.3. Dynamic Value Monitor RequestMonitor is different from other kinds of requests in that it:
The proxy mechanism works as follows:
Figure 2: Interaction diagram that shows monitor creation. Apart from the seemingly complex interaction diagram, the request structure for the monitor is relatively simple:
Table 4: Request structure for dynamic value monitor. 3.4. Characteristic Read RequestThe request structure is the same as in Dynamic Value Get Request, but with the following differences:
Table 5: Description of the table The plug adds a new response with the characteristic's value (of type type specified in Request.getProperties()) and calls back the database, which completes the request. The code snippet for the characteristic get is basically similar to the dynamic value get. 3.5. Dynamic Value History RequestHistory request is a single request, which, similarly to a monitor request, results in a creation of a transient object in the pluggable layer. Therefore the proxy mechanism is used, in a similar fashion to monitors. History request is submitted in response to an invocation of a method declared in Datatypes HistoryAccess interface:
The proxy mechanism works as follows:
Table 6: Request structure for dynamic value history request. 3.6. Grouped Characteristic Read Request3.7. Dynamic Value Asynchronous Get RequestThe following table lists the request structure for the asynchronous dynamic value get operation:
Table 7: Request structure for asynchronous dynamic value get. When this request is received by the plug, the plug must immediately respond by calling back database with message requestStarted. Then, the plug must dispatch the request to the remote layer in such a way so as not to block the calling thread. In other words, the plug must not wait for the response from the underlying data source, but must provide a callback and return as soon as possible. When the return value is obtained from the remote layer, the plug must use the RequestResponseFactory interface to create a new Response, set the error and completion fields, leave the qualifier field empty, and insert a new value into the Response. To reiterate: response construction does not occur in the thread in which the request was submitted. The response must be of the ResponseType type. The plug finally performs Request.addResponse() to add a new response to the request and invokes requestNewResponse callback on the database. This finishes the processing of the request. Apart from the threading issues, the behavior of the value asynchronous get is the same as the behavior of the syncrhonous (normal) get. The model will submit this request as a RequestType.SINGLE_REQUEST, which means that the first response is also the last response and that the request automatically terminates when the first response is received. 3.8. Dynamic Value Asynchronous Set RequestThe following table lists the request structure for the asynchronous dynamic value get operation:
Table 8: Request structure for asynchronous dynamic value set. When this request is received by the plug, the plug must immediately respond by calling back database with message requestStarted. Then, the plug must dispatch the request to the remote layer in such a way so as not to block the calling thread. In other words, the plug must not wait for the response from the underlying data source, but must provide a callback and return as soon as possible. When the return value is obtained from the remote layer, the plug must use the RequestResponseFactory interface to create a new Response, set the error and completion fields, leave the qualifier field empty, and insert a new value into the Response. To reiterate: response construction does not occur in the thread in which the request was submitted. The response must be of the ResponseType type. The plug finally performs Request.addResponse() to add a new response to the request and invokes requestNewResponse callback on the database. This finishes the processing of the request. Apart from the threading issues, the behavior of the value asynchronous get is the same as the behavior of the syncrhonous (normal) get. The model will submit this request as a RequestType.SINGLE_REQUEST, which means that the first response is also the last response and that the request automatically terminates when the first response is received. Document History
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
![]() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||