12.26. OData Version 4 Translator
12.26. OData Version 4 Translator 12.26.1. OData Version 4 Translator The OData V4 translator, known by the type name "odata4" exposes the OData Version 4 data sources and uses the Teiid WS resource adapter for making web service calls. This translator is an extension of the Web Services Translator. Use the Open Data (OData) 4 Web Protocol to standardize APIs for accessing data from a variety of sources. OData is an abstraction layer that allows you to access data from such places as databases, file systems and content management systems. OData provides a REST-based protocol for various database operations. OData is useful if you intend to build RESTful APIs as it standardizes the ways in which you build and consume such things as request and response headers, payload formats, status codes, query options and so forth. By standardizing these, it frees you to focus on developing your business logic. Red Hat JBoss Data Virtualization can expose any data source as an OData-based web service. Red Hat JBoss Data Virtualization maps OData 4 Conceptual Schema Documentation Language (CSDL) documents to relational entities. It does this in order to convert OData information into a relational schema understood by Data Virtualization. Here are the mappings to show how the OData elements are converted: Table 12.25. Mappings OData Relational Entity EntitySet Table EntityType Table. (This is only mapped if the EntityType is exposed as the EntitySet in the Entity Container.) ComplexType Table. (This is mapped only if the complex type is used as a property in the exposed EntitySet. This table will be either a child table with a foreign key [one to one] or [one to many] relationship with its parent.) FunctionImport Procedure. (If the return type is EntityType or ComplexType, the procedure will return a table.) ActionImport Procedure. (If the return type is EntityType or ComplexType, the procedure will return a table.) NavigationProperties Table. (Navigation properties are exposed as tables. These tables are created with foreign key relationships to the parent.) After the entities are generated by these mappings, the translator maps CRUD operations to them based on them that are derived from the submitted SQL. The OData translator works in a similar way to the JDBC translator in that, once the metadata is imported from the source system and exposed in relational terms, then that source can be queried as if the EntitySets, Function Imports and Action Imports were based locally on the Red Hat JBoss Data Virtualization system. Here is a sample virtual database that can read the metadata service from the TripPin example (which you can find on http://odata.org ): Configure your resource adapter to look like this: Deployed the virtual database. Connect to it using the JDBC driver. You can then issue SQL queries like these: Note People_UserName is implicitly added by the metadata. 12.26.1.1. Translator Configuration Options 12.26.1.1.1. Execution Options Use execution properties to extend or limit the functionality of the translator to match the capabilities of the physical data source. You will sometimes need to adjust the defaults so that the translator works in the manner you expect. Table 12.26. Execution Properties Name Description Default SupportsOdataCount Supports USDcount true SupportsOdataFilter Supports USDfilter true SupportsOdataOrderBy Supports USDorderby true SupportsOdataSkip Supports USDskip true SupportsOdataTop Supports USDtop true SupportsUpdates Supports INSERT/UPDATE/DELETE true Sometimes the OData server might not have implemented the entire OData specification. If your OData implementation does not support a certain feature, then turn off the corresponding capability via the "execution Properties" so that you do not encounter any unexpected behaviour. Here is how you do so: To turn off USDfilter, add the following configuration to your vdb.xml file: Use "odata-override" as the source model's translator name. 12.26.1.1.2. Importer Properties If you wish, you can set the importer's properties. This allows you to define the behavior of the translator when it is importing the metadata from the physical source giving you more flexibility: Table 12.27. Importer Properties Name Description Default schemaNamespace This is the namespace of the schema to import. null In this example, the importer is told to import only those tables and views from the TripPin service that have been exposed on odata.org: Note You can leave this property undefined. If you do so, the EntityContainer's default name is used instead. 12.26.1.1.3. JCA Resource Adapter The resource adapter for this translator is a web service data source. Important You cannot perform native or direct query execution through the OData translator. However, to work around this you can use the Web Services Translator's invokehttp method directly to issue a REST-based call. You can then parse the results with SQLXML.
<vdb name="trippin" version="1"> <model name="trippin"> <source name="odata4" translator-name="odata4" connection-jndi-name="java:/tripDS"/> </model> </vdb> <resource-adapter id="trippin"> <module slot="main" id="org.jboss.teiid.resource-adapter.webservice"/> <transaction-support>NoTransaction</transaction-support> <connection-definitions> <connection-definition class-name="org.teiid.resource.adapter.ws.WSManagedConnectionFactory" jndi-name="java:/tripDS" enabled="true" use-java-context="true" pool-name="teiid-trip-ds"> <config-property name="EndPoint"> http://services.odata.org/V4/(S(va3tkzikqbtgu1ist44bbft5))/TripPinServiceRW </config-property> </connection-definition> </connection-definitions> </resource-adapter> SELECT * FROM trippin.People; SELECT * FROM trippin.People WHERE UserName = 'russelwhyte'; SELECT * FROM trippin.People p INNER JOIN trippin.People_Friends pf ON p.UserName = pf.People_UserName; EXEC GetNearestAirport(lat, lon) ; <translator name="odata-override" type="odata"> <property name="SupportsOdataFilter" value="false"/> </translator> <property name="importer.schemaNamespace" value="Microsoft.OData.SampleService.Models.TripPin"/>