<html>
<head>
    <base href="https://docs.jboss.org/author">
            <link rel="stylesheet" href="/author/s/en/2172/19/5/_/styles/combined.css?spaceKey=TEIID&amp;forWysiwyg=true" type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://docs.jboss.org/author/display/TEIID/REST+Service+Through+VDB">REST Service Through VDB</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://docs.jboss.org/author/display/~rareddy">Ramesh Reddy</a>
    </h4>
        <br/>
                         <h4>Changes (3)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >where &quot;sample_1&quot; is context, &quot;view&quot; is model name, &quot;g1&quot; is URI, and 123 is parameter \{p1\} from URI. If you defined a procedure that returns a XML content, then REST service call should be called with &quot;accepts&quot; HTTP header of &quot;application/xml&quot;. Also, if you defined a procedure that returns a JSON content and PRODUCES  property is defined &quot;json&quot; then HTTP client call should include the &quot;accepts&quot; header of &quot;application/json&quot;. In the situations where &quot;accepts&quot; header is missing, and only one procedure is defined with unique path, that procedure will be invoked. If there are multiple procedures with same URI path, for example one generating XML and another generating JSON content then &quot;accepts&quot; header directs the REST engine as to which procedure should be invoked to get the results. A wrong &quot;accepts&quot; header will result in error. <br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">{warning} <br>Make sure that the number of parameters defined on the URI must match to the parameters defined on procedure definition. An error with parameter definition will result in procedure being skipped from generation of REST based service or error with &#39;GET&#39; based methods. &#39;POST&#39; methods do not need to be defined with URI paths, the procedure parameters are automatically added as @FormParam annotations on the generated procedure. <br>{warning} <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">{tip:title=&quot;GET Methods&quot;} <br>When designing the procedures that will be invoked through GET based call, the input parameters for procedures can be defined in the PATH of the URI, as the \{p1} example above, or they can also be defined as query parameter, or combination of both. For example <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">{code} <br>http://{host}:8080/sample_1/view/g1?p1=123 <br>http://{host}:8080/sample_1/view/g1/123?p2=foo <br>{code} <br> <br>Make sure that the number of parameters defined on the URI and query match to the parameters defined on procedure definition. If you defined a default value for a parameter on the procedure, and that parameter going to be passed in query parameter on URL then you have choice to omit that query parameter, if you defined as PATH you must supply a value for it. <br>{tip} <br> <br>{tip:title=&quot;POST methods&quot;} <br>&#39;POST&#39; methods MUST not be defined with URI with PATHS for parameters as in GET operations, the procedure parameters are automatically added as @FormParam annotations on the generated procedure. A client invoking this service must use FORM to post the values for the parameters. The FORM field names MUST match the names of the procedure parameters names. <br> <br>If any one of the procedure parameters are BLOB, CLOB, XML or VARBINARY type, then POST operation can be only invoked using &quot;multipart/form-data&quot; [RFC-2388|https://www.ietf.org/rfc/rfc2388.txt] protocol. This allows user to upload large binary or XML files efficiently to Teiid using streaming&quot; <br>{tip} <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h3. Security on Generated Services <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <p>With help of <a href="/author/display/TEIID/DDL+Metadata" title="DDL Metadata">DDL Metadata</a> variety of metadata can be defined on VDB schema models. This metadata is not limited to just defining the tables, procedures and functions. The capabilities of source systems or any extensions to metadata can also be defined on the schema objects using the OPTIONS clause. One such extension properties that Teiid defines is to expose Teiid procedures as REST based services.</p>

<h3><a name="RESTServiceThroughVDB-ExposeTeiidProcedureasRestService"></a>Expose Teiid Procedure as Rest Service</h3>

<p>One can define below REST based properties on a Teiid virtual procedure, and when the VDB is deployed the Teiid VDB deployer will analyse the metadata and deploy a REST service automatically. When the VDB un-deployed the REST service also deployed.</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Property Name </th>
<th class='confluenceTh'> Description </th>
<th class='confluenceTh'> Is Required </th>
<th class='confluenceTh'> Allowed Values </th>
</tr>
<tr>
<td class='confluenceTd'> METHOD </td>
<td class='confluenceTd'> HTTP Method to use </td>
<td class='confluenceTd'> Yes </td>
<td class='confluenceTd'> GET &#124; POST&#124; PUT &#124; DELETE </td>
</tr>
<tr>
<td class='confluenceTd'> URI </td>
<td class='confluenceTd'> URI of procedure </td>
<td class='confluenceTd'> Yes </td>
<td class='confluenceTd'> ex:/procedure </td>
</tr>
<tr>
<td class='confluenceTd'> PRODUCES </td>
<td class='confluenceTd'> Type of content produced by the service </td>
<td class='confluenceTd'> no </td>
<td class='confluenceTd'> xml &#124; json &#124; plain &#124; any text </td>
</tr>
<tr>
<td class='confluenceTd'> CHARSET </td>
<td class='confluenceTd'> When procedure returns Blob, and content type text based, this character set to used to convert the data </td>
<td class='confluenceTd'> no </td>
<td class='confluenceTd'> US-ASCII &#124; UTF-8 </td>
</tr>
</tbody></table>
</div>


<p>The above properties must be defined with NAMESPACE 'http://teiid.org/rest' on the metadata. Here is an example VDB that defines the REST based service.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Example VDB with REST based metadata properties</b></div><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: xml; gutter: false" style="font-size:12px; font-family: ConfluenceInstalledFont,monospace;">
&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;
&lt;vdb name="sample" version="1"&gt;    
    &lt;property name="{http://teiid.org/rest}auto-generate" value="true"/&gt;

    &lt;model name="PM1"&gt;
        &lt;source name="text-connector" translator-name="loopback" /&gt;
         &lt;metadata type="DDL"&gt;&lt;![CDATA[
                CREATE FOREIGN TABLE G1 (e1 string, e2 integer);
                CREATE FOREIGN TABLE G2 (e1 string, e2 integer);
        ]]&gt; &lt;/metadata&gt;
    &lt;/model&gt;
    &lt;model name="View" type ="VIRTUAL"&gt;
         &lt;metadata type="DDL"&gt;&lt;![CDATA[
            SET NAMESPACE 'http://teiid.org/rest' AS REST;
            CREATE VIRTUAL PROCEDURE g1Table(IN p1 integer) RETURNS TABLE (xml_out xml) OPTIONS (UPDATECOUNT 0, "REST:METHOD" 'GET', "REST:URI" 'g1/{p1}')
            AS
            BEGIN
                SELECT XMLELEMENT(NAME "rows", XMLATTRIBUTES (g1Table.p1 as p1), XMLAGG(XMLELEMENT(NAME "row", XMLFOREST(e1, e2)))) AS xml_out FROM PM1.G1;
            END
            ]]&gt; &lt;/metadata&gt;
    &lt;/model&gt;

&lt;/vdb&gt;
</pre>
</div></div>

<div class='panelMacro'><table class='infoMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/author/images/icons/emoticons/information.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>&lt;property name="{<a href="http://teiid.org/rest" class="external-link" rel="nofollow">http://teiid.org/rest</a>}auto-generate" value="true"/&gt;, can be used to control the generation of the REST based WAR based on the VDB. This property along with at least one procedure with REST based extension metadata is required to generate a REST WAR file. Also, the procedure needs to return result set with single column of either XML, Clob, Blob or String. When PRODUCES property is not defined, this property is derived from the result column that is projected out.</td></tr></table></div>

<p>when the above VDB is deployed in the JBoss AS + Teiid server, and if the VDB is valid and after the metadata is loaded then a REST war generated automatically and deployed into the local JBoss AS server. The REST VDB is deployed with "{vdb-name}_{vdb-version}" context. The model name is prepended to uri of the service call. For example the procedure in above example can be accessed as</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px; font-family: ConfluenceInstalledFont,monospace;">
http://{host}:8080/sample_1/view/g1/123
</pre>
</div></div>

<p>where "sample_1" is context, "view" is model name, "g1" is URI, and 123 is parameter {p1} from URI. If you defined a procedure that returns a XML content, then REST service call should be called with "accepts" HTTP header of "application/xml". Also, if you defined a procedure that returns a JSON content and PRODUCES  property is defined "json" then HTTP client call should include the "accepts" header of "application/json". In the situations where "accepts" header is missing, and only one procedure is defined with unique path, that procedure will be invoked. If there are multiple procedures with same URI path, for example one generating XML and another generating JSON content then "accepts" header directs the REST engine as to which procedure should be invoked to get the results. A wrong "accepts" header will result in error.</p>

<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/author/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td><b>"GET Methods"</b><br />When designing the procedures that will be invoked through GET based call, the input parameters for procedures can be defined in the PATH of the URI, as the {p1} example above, or they can also be defined as query parameter, or combination of both. For example

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px; font-family: ConfluenceInstalledFont,monospace;">
http://{host}:8080/sample_1/view/g1?p1=123
http://{host}:8080/sample_1/view/g1/123?p2=foo
</pre>
</div></div>

<p>Make sure that the number of parameters defined on the URI and query match to the parameters defined on procedure definition. If you defined a default value for a parameter on the procedure, and that parameter going to be passed in query parameter on URL then you have choice to omit that query parameter, if you defined as PATH you must supply a value for it.</p></td></tr></table></div>

<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/author/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td><b>"POST methods"</b><br />'POST' methods MUST not be defined with URI with PATHS for parameters as in GET operations, the procedure parameters are automatically added as @FormParam annotations on the generated procedure. A client invoking this service must use FORM to post the values for the parameters. The FORM field names MUST match the names of the procedure parameters names.

<p>If any one of the procedure parameters are BLOB, CLOB, XML or VARBINARY type, then POST operation can be only invoked using "multipart/form-data" <a href="https://www.ietf.org/rfc/rfc2388.txt" class="external-link" rel="nofollow">RFC-2388</a> protocol. This allows user to upload large binary or XML files efficiently to Teiid using streaming"</p></td></tr></table></div>

<h3><a name="RESTServiceThroughVDB-SecurityonGeneratedServices"></a>Security on Generated Services</h3>

<p>By default all the generated Rest based services are secured using "HTTPBasic" with security domain "teiid-security"  and with security role "rest". However, these properties can be customized by defining the then in vdb.xml file. </p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Example vdb.xml file security specification</b></div><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: xml; gutter: false" style="font-size:12px; font-family: ConfluenceInstalledFont,monospace;">
&lt;vdb name="sample" version="1"&gt;
    &lt;property name="{http://teiid.org/rest}auto-generate" value="true"/&gt;
    &lt;property name="{http://teiid.org/rest}security-type" value="HttpBasic"/&gt;
    &lt;property name="{http://teiid.org/rest}security-domain" value="teiid-security"/&gt;
    &lt;property name="{http://teiid.org/rest}security-role" value="example-role"/&gt;
    &lt;property name="{http://teiid.org/rest}passthrough-auth" value="true"/&gt;

    ...
&lt;/vdb&gt;
</pre>
</div></div>

<ul>
        <li><em>security-type</em> - defines the security type. allowed values are "HttpBasic" or "none". If omitted will default to "HttpBasic"</li>
        <li><em>security-domain</em> - defines JAAS security domain to be used with HttpBasic. If omitted will default to "teiid-security"</li>
        <li><em>security-role</em> - security role that HttpBasic will use to authorize the users. If omitted the value will default to "rest"</li>
        <li><em>passthough-auth</em> - when defined the pass-through-authentication is used to login in to Teiid. When this is set to "true", make sure that the "embedded" transport configuration in "standalone-teiid.xml" has defined a security-domain that can be authenticated against. Failure to add the configuration change will result in authentication error. Defaults to false.</li>
</ul>


<div class='panelMacro'><table class='infoMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/author/images/icons/emoticons/information.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td><b>ws-security</b><br />it is our intention to provide other types of security based on ws-security in future releases.</td></tr></table></div>

<h3><a name="RESTServiceThroughVDB-SpecialAdHocRestServices"></a>Special Ad-Hoc Rest Services</h3>

<p>Apart from the explicitly defined procedure based rest services, the generated jax-rs war file will also implicitly include a special rest based service under URI "/query" that can take any XML or JSON producing SQL as parameter and expose the results of that query as result of the service. This service is defined with "POST", accepting a Form Parameter named "sql". For example, after you deploy the VDB defined in above example, you can issue a HTTP POST call as </p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px; font-family: ConfluenceInstalledFont,monospace;">
    http://localhost:8080/sample_1/view/query
    sql=SELECT XMLELEMENT(NAME "rows",XMLAGG(XMLELEMENT(NAME "row", XMLFOREST(e1, e2)))) AS xml_out FROM PM1.G1
</pre>
</div></div>

<p>A sample HTTP Request from Java can be made like below</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px; font-family: ConfluenceInstalledFont,monospace;">

        public static String httpCall(String url, String method, String params) throws Exception {
                StringBuffer buff = new StringBuffer();
                HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
                connection.setRequestMethod(method);
                connection.setDoOutput(true);
                
                if (method.equalsIgnoreCase("post")) {
                        OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream());
                    wr.write(params);
                    wr.flush();
                }
                
                BufferedReader serverResponse = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String line;
                while ((line = serverResponse.readLine()) != null) {
                        buff.append(line);
                }
                return buff.toString();
        }

        public static void main(String[] args) throws Exception {
            String params = URLEncoder.encode("sql", "UTF-8") + "=" + URLEncoder.encode("SELECT XMLELEMENT(NAME "rows",XMLAGG(XMLELEMENT(NAME "row", XMLFOREST(e1, e2)))) AS xml_out FROM PM1.G1", "UTF-8");
            httpCall("http://localhost:8080/sample_1/view/query", "POST", params);
        }
</pre>
</div></div>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;" class="grey">
                        <a href="https://docs.jboss.org/author/users/removespacenotification.action?spaceKey=TEIID">Stop watching space</a>
            <span style="padding: 0px 5px;">|</span>
                <a href="https://docs.jboss.org/author/users/editmyemailsettings.action">Change email notification preferences</a>
</div>
        <a href="https://docs.jboss.org/author/display/TEIID/REST+Service+Through+VDB">View Online</a>
        |
        <a href="https://docs.jboss.org/author/pages/diffpagesbyversion.action?pageId=53117684&revisedVersion=9&originalVersion=8">View Changes</a>
                |
        <a href="https://docs.jboss.org/author/display/TEIID/REST+Service+Through+VDB?showComments=true&amp;showCommentArea=true#addcomment">Add Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>