10 Replies Latest reply on Oct 10, 2013 5:44 AM by madhu.garimilla

    Does Teiid REST service support a Blob Input?

    madhu.garimilla

      Hi,

       

      I am trying to upload a file to my Teiid REST service which is backed by a virtual procedure. I have defined the input type as blob. Inside the procedure i am trying to make a call to another UDF which takes this blob input and reads the stream. Does Teiid supports a Blob type input in REST service? Does it handle automatic type conversion if i am writing the file to the OutputStream of the HttpUrlConnection object like below?


      String userPassword =  "user:user";

      String encoding = new BASE64Encoder().encode(userPassword.getBytes());

       

      HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();

      connection.setRequestProperty("Authorization", "Basic " + encoding);

      connection.setRequestProperty("Content-Type", "multipart/form-data");

      connection.setRequestMethod("POST");

      connection.setDoOutput(true);

       

      FileInputStream in = new FileInputStream( new File("C:\\SampleWeb.war") );

      OutputStream out = connection.getOutputStream();

      byte[] data = new byte[ 4096 ];

      int bytesRead = 0;

      while(( bytesRead = in.read( data )) != -1 ){

      out.write(data, 0, bytesRead );

      out.flush();

      }

      and here is my model definition inside the vdb

       

      <model name="deploy" type ="VIRTUAL">

               <metadata type="DDL"><![CDATA[

                  SET NAMESPACE 'http://teiid.org/rest' AS REST;

                  CREATE VIRTUAL PROCEDURE g1Table(IN p1 blob) RETURNS TABLE (xml_out boolean) OPTIONS (UPDATECOUNT 0, "REST:METHOD" 'POST', "REST:URI" '')

                  AS

                  BEGIN

                      SELECT testmodel.upload(p1) AS xml_out FROM (SELECT 1) as T;

                  END

                  ]]> </metadata>

          </model>

        • 1. Re: Does Teiid REST service support a Blob Input?
          rareddy

          It does support POST and there is no restriction of the type to use. However it does not handle automatic type conversion, try writing a Blob object to output stream. I have to say I have not tested that scenario. Also not certain for the multi-part stuff will work with Resteasy framework.

           

          Ramesh..

          • 2. Re: Does Teiid REST service support a Blob Input?
            madhu.garimilla

            Ramesh, I created Blob using the below code and tried to write it using ObjectOutputStream to HttpUrlConnection but it failed as it cannot be serialized.

             

            Blob blob = new org.teiid.core.types.BlobImpl(new org.teiid.core.types.InputStreamFactory() {

             

                        @Override

                        public InputStream getInputStream() throws IOException {

                            return new FileInputStream("C:\\sample.war");

                        }

                    });

             

            Then i tried using SerialBlob but that also resulted in the same error as "java.io.NotSerializableException" . This does work in JDBC but not sure how to make it work with Teiid REST service. Do you have any suggestions? multipart stuff is working with the normal jboss resteasy framework.

            • 3. Re: Does Teiid REST service support a Blob Input?
              rareddy

              What is client code look like?

               

              Also, try building BlobImpl or SerialBlob with full byte contents of your data.

              • 4. Re: Does Teiid REST service support a Blob Input?
                madhu.garimilla

                Here is my client code.

                 

                        String userPassword =  "user:user";

                        String encoding = new BASE64Encoder().encode(userPassword.getBytes());

                       

                        StringBuffer buff = new StringBuffer();

                        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();

                        connection.setRequestProperty("Authorization", "Basic " + encoding);

                        connection.setRequestProperty("Content-Type","multipart/form-data;");

                        connection.setChunkedStreamingMode(4096);

                        connection.setRequestProperty("Connection", "Keep-Alive");

                        connection.setRequestMethod("POST");

                        connection.setDoOutput(true);

                       

                        Blob blob = new org.teiid.core.types.BlobImpl(new org.teiid.core.types.InputStreamFactory() {

                            @Override

                            public InputStream getInputStream() throws IOException {

                                return new FileInputStream("C:\\sample.war");

                            }

                        });

                       

                        SerialBlob slob = new SerialBlob(blob);       

                        ObjectOutputStream outputStream = new ObjectOutputStream(connection.getOutputStream());

                 

                                    try {

                                        outputStream.writeObject(slob);

                                        outputStream.flush();

                                    } catch (Exception e) {

                                        e.printStackTrace();

                                    }

                                              

                        BufferedReader serverResponse = new BufferedReader(new InputStreamReader(connection.getInputStream()));

                        String line;

                        while ((line = serverResponse.readLine()) != null) {

                            buff.append(line);

                        }

                        System.out.println(buff);

                • 5. Re: Re: Does Teiid REST service support a Blob Input?
                  rareddy

                  Try

                   

                  SerialBlob blob = new SerialBlob(readFileAsBytes("c:\\sample.war");
                  ...
                  
                  
                  
                  static byte[] readFileAsBytes(String name) throws IOException {
                    FileInputStream in = new FileInputStream(name);
                      ByteArrayOutputStream out = new ByteArrayOutputStream();
                      try {
                          while(true) {
                          byte b = (byte)in.read();
                          if (b == -1) {
                          break;
                          }
                          out.write(b);
                          }
                      } finally {
                      in.close();
                      out.close();
                      }
                      return out.toByteArray();    
                  }
                  

                   

                  Ramesh..

                  • 6. Re: Re: Re: Does Teiid REST service support a Blob Input?
                    madhu.garimilla

                    Hi Ramesh, I tried using the byte array as suggested. Now the serialization error is gone but my UDF is still getting null input for Blob object. There were no exceptions reported in the jboss/eclipse consoles. Attached the Client and VDB/UDF files i am using.

                    • 7. Re: Re: Re: Does Teiid REST service support a Blob Input?
                      shawkins

                      From what I can see the code is not setup to handle binary inputs in any direct fashion.  If you are handling large blobs then we'll have to look at enhancing the code.

                       

                      Otherwise if your content is not too large you can set the content as a string - for example using BASE64 or HEX encoding, then use the teiid function to_bytes(string_val, 'BASE64') to convert back to bytes when you want to pass the value to your upload function.

                       

                      Steve

                      • 8. Re: Does Teiid REST service support a Blob Input?
                        madhu.garimilla

                        Hi Steve, We are trying to upload large files as Blobs. So, we will not be able to use encoding technique. Shall i create a JIRA issue for this enhancement?

                        • 9. Re: Does Teiid REST service support a Blob Input?
                          shawkins

                          Yes, an issue is needed as all current parameter handling is done through strings.  The RestEasy integration looks like my be a bit tricky in this case - http://www.mkyong.com/webservices/jax-rs/file-upload-example-in-resteasy/

                           

                          Steve

                          • 10. Re: Does Teiid REST service support a Blob Input?
                            madhu.garimilla