4 Replies Latest reply on Jun 25, 2014 11:33 AM by shawkins

    Content is not allowed in prolog.

    lewis.watson

      Hello,

       

      I'm in the process of setting up a REST web API as a data source in JBoss Data Virtualization. I created a API using Python REST API Framework — Eve 0.4-dev documentation but ran into difficulties when previewing my view.

       

      Screenshot from 2014-06-19 15:57:08.png

       

      SELECT
              A.location AS location, A.role AS role, A.firstname AS firstname, A.born AS born, A.lastname AS lastname
          FROM
              (EXEC Eve_People_source.invokeHttp('GET', null, 'http://eve-demo.herokuapp.com/people', 'TRUE')) AS f, XMLTABLE('/resource/resource' PASSING XMLPARSE(DOCUMENT f.result) COLUMNS location string PATH 'location/text()', role string PATH 'role/text()', firstname string PATH 'firstname/text()', born string PATH 'born/text()', lastname string PATH 'lastname/text()') AS A
      

       

      SQL Results

       

      select * from "Eve_People_view"."people"
      TEIID30151 Remote org.teiid.core.TeiidProcessingException: TEIID30151 Error building Source for context item.
      Elapsed Time:  0 hr, 0 min, 1 sec, 896 ms.
      

       

      Server Console

       

      15:55:56,751 ERROR [stderr] (Worker1_QueryProcessorQueue3) Error on line 1 column 1 
      15:55:56,751 ERROR [stderr] (Worker1_QueryProcessorQueue3)   SXXP0003: Error reported by XML parser: Content is not allowed in prolog.
      15:55:56,754 WARN  [org.teiid.PROCESSOR] (Worker0_QueryProcessorQueue2) TEIID30020 Processing exception for request 0NOkK/7jXj13.0 'TEIID30151 Error building Source for context item.'. Originally TeiidProcessingException 'Content is not allowed in prolog.' org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source). Enable more detailed logging to see the entire stacktrace.
      

       

      I believe the problem comes down to a missing line in the XML response from http://eve-demo.herokuapp.com/people.

       

      It currently returns

       

      <resource href="eve-demo.herokuapp.com/people" title="people">
           <link rel="parent" href="eve-demo.herokuapp.com" title="home"/><resource href="eve-demo.herokuapp.com/people/539fdea42b996e00026114fb" title="person">
      ...
      

       

      but I think Teiid wants

       

      <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
      <resource href="eve-demo.herokuapp.com/people" title="people">
           <link rel="parent" href="eve-demo.herokuapp.com" title="home"/><resource href="eve-demo.herokuapp.com/people/539fdea42b996e00026114fb" title="person">
      ...
      


      I don't know how common it is for REST API's to drop the "<?xml..." line but I think ideally Teiid should be able to handle it. Is there something I can do at the Teiid end or will I have to rely on the API maintainer to provide 100% valid XML?


      Thanks in advance!


      Lewis

        • 1. Re: Content is not allowed in prolog.
          lewis.watson

          My theory about the missing XML deceleration may be wrong...

           

          I set up a REST api at http://95.138.165.64:5002/cases that returns

           

          <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
          <resource href="/cases" title="cases">
              <link rel="parent" href="" title="home"/>
              <_meta>
                  <max_results>25</max_results>
                  <total>5</total>
                  <page>1</page>
              </_meta>
              <resource href="/cases/53a807f61571734c148fc8c9" title="case">
                  ...
          
              </resource>
              ...
          </xml>
          


          And with a transformation


          SELECT
                  A.status AS status, A.received AS received, A.archived AS archived, A.destruction_date AS destruction_date, A.registered AS registered, A.review_requested AS review_requested, A.complexity_rating AS complexity_rating, A.finalised AS finalised, A.crest_number AS crest_number, A.location AS location, A.type AS type
              FROM
                  (EXEC RackspaceEveCases_source.invokeHttp('GET', null, 'http://95.138.165.64:5002/cases', 'TRUE')) AS f, XMLTABLE('/resource/resource' PASSING XMLPARSE(DOCUMENT f.result) COLUMNS status string PATH 'status/text()', received string PATH 'received/text()', archived string PATH 'archived/text()', destruction_date string PATH 'destruction_date/text()', registered string PATH 'registered/text()', review_requested string PATH 'review_requested/text()', complexity_rating string PATH 'complexity_rating/text()', finalised string PATH 'finalised/text()', crest_number string PATH 'crest_number/text()', location string PATH 'location/text()', type string PATH 'type/text()') AS A
          

           

          I still get a "Content is not allowed in prolog" error

           

          12:05:55,408 WARN  [org.teiid.PROCESSOR] (Worker4_QueryProcessorQueue13) TEIID30020 Processing exception for request KiWHPrV70/ln.0 'TEIID30151 Error building Source for context item.'. Originally TeiidProcessingException 'Content is not allowed in prolog.' org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source). Enable more detailed logging to see the entire stacktrace.
          

           

          I've left my example API running at http://95.138.165.64:5002/cases if that helps. It will return XML or JSON depending on the request header.

           

          Regards

           

          Lewis

          • 2. Re: Content is not allowed in prolog.
            shawkins

            Using invokeHttp, I'm seeing the json result back - which will give the prolog error that you are seeing.  Are you needing an accepts or some other header value to be set?

            • 3. Re: Re: Content is not allowed in prolog.
              lewis.watson

              Hi Steven, thanks for looking into this for me.

               

              How are you able to look at the reply? I've been looking around the console output but I can't see anything about the raw response from the server.

               

              Looking at the documentation for invokeHTTP I see that it can take a "contentType" string parameter

              Procedure invokeHttp(action in STRING, request in OBJECT, endpoint in STRING, contentType out STRING) returns BLOB

               

              So I tried changing my invokeHttp call to be

               

              EXEC RackspaceEveCases_source.invokeHttp(action => 'GET', endpoint => 'http://95.138.165.64:5002/cases', stream => TRUE, contentType => 'application/xml')
              

               

              But I still get the prolog error.

               

              08:24:31,003 ERROR [stderr] (Worker3_QueryProcessorQueue7) Error on line 1 column 1 
              08:24:31,005 ERROR [stderr] (Worker3_QueryProcessorQueue7)   SXXP0003: Error reported by XML parser: Content is not allowed in prolog.
              08:24:31,008 WARN  [org.teiid.PROCESSOR] (Worker2_QueryProcessorQueue6) TEIID30020 Processing exception for request eqvjbAqkH4ob.0 'TEIID30151 Error building Source for context item.'. Originally TeiidProcessingException 'Content is not allowed in prolog.' org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source). Enable more detailed logging to see the entire stacktrace.
              

               

              In my previous attempts to get this working I disabled JSON entirely from the Python-eve REST side. However, without viewing the raw response I can't rule out JSON still sneaking into the mix. For now I've left JSON enabled on http://95.138.165.64:5002/cases as I need Teiid to be able set the contentType.

               

              Regards

               

              Lewis

              • 4. Re: Content is not allowed in prolog.
                shawkins

                > How are you able to look at the reply? I've been looking around the console output but I can't see anything about the raw response from the server.

                 

                The response isn't logged, but you can just select the invokeHttp result and inspect it in a client.

                 

                > So I tried changing my invokeHttp call to be

                 

                The output parameter is for the result value, it is not an input.  I think you'll have to rely on something like:  https://issues.jboss.org/browse/TEIID-3016