Camel-Restlet 2.14.0 DecodeRepresentation

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Camel-Restlet 2.14.0 DecodeRepresentation

sandp

I'm trying to use GZIP with Camel-restlet, this is how I GZIP the entity in response before I send the response out.

=================Processor====================
public void process(Exchange exchange) throws Exception {
Message message =exchange.getIn();
 Representation representation = new EncodeRepresentation(Encoding.GZIP, new StringRepresentation(message.getBody(String.class), MediaType.TEXT_XML));
}

On the client side I'm facing issue retrieving and decoding the gzipped entity. I tried several ways but failed. There's not much information on how to do this. Appreciate if you could point me in the right direction.


Client Side.. Retrieveing response from Exchange MEssage

 String stream =  resultEndpoint.getExchanges().get(0).getIn().getBody(String.class);
 Representation representations = new DecodeRepresentation(new StringRepresentation(stream));
Reply | Threaded
Open this post in threaded view
|

Re: Camel-Restlet 2.14.0 DecodeRepresentation

sandp
There is no WrappedRepresentation in the entity of the Response object.

 Response response = exchange.getIn().getHeader(RestletConstants.RESTLET_RESPONSE, Response.class);
Representation representation=response.getEntity();
//The representation is missing the WrappedRepresentation.  I'm not sure how decoding can be done without it.



Reply | Threaded
Open this post in threaded view
|

Re: Camel-Restlet 2.14.0 DecodeRepresentation

sandp
Looks like there's a bug in file org.apache.camel.component.restlet.DefaultRestletBinding.java


Method starts at line number 292
public void populateExchangeFromRestletResponse(Exchange exchange, Response response) throws Exception {
        for (Map.Entry<String, Object> entry : response.getAttributes().entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (!headerFilterStrategy.applyFilterToExternalHeaders(key, value, exchange)) {
                exchange.getOut().setHeader(key, value);
                LOG.debug("Populate exchange from Restlet response header: {} value: {}", key, value);
            }
        }

        // set response code
        int responseCode = response.getStatus().getCode();
        exchange.getOut().setHeader(Exchange.HTTP_RESPONSE_CODE, responseCode);

        // set restlet response as header so end user have access to it if needed
        exchange.getOut().setHeader(RestletConstants.RESTLET_RESPONSE, response);

        if (response.getEntity() != null) {
            // get content type
            MediaType mediaType = response.getEntity().getMediaType();
            if (mediaType != null) {
                LOG.debug("Setting the Content-Type to be {}",  mediaType.toString());
                exchange.getOut().setHeader(Exchange.CONTENT_TYPE, mediaType.toString());
            }
            if (mediaType != null && mediaType.equals(MediaType.APPLICATION_OCTET_STREAM)) {
                exchange.getOut().setBody(response.getEntity().getStream());
            } else {
                // get content text
  Line 320              String text = response.getEntity().getText();
  Line 321                 LOG.debug("Populate exchange from Restlet response: {}", text);
  Line 322                 exchange.getOut().setBody(text);
            }

        }

        // preserve headers from in by copying any non existing headers
        // to avoid overriding existing headers with old values
        MessageHelper.copyHeaders(exchange.getIn(), exchange.getOut(), false);
    }

The bolded else part above gets the text from the entity in the Response and  sets it on the OUT Message of the Exchange. But, at this point the response.getEntity() is of type InputRepresentation with MediaType.TEXT_XML and GZIP encoded, so why not pass the entity along as is? When its converted to a  String its tampered and lost (remember its encoded type is GZIP).

To make it work, we could change the code to something like:
replace lines 320 - 322 with
  exchange.getOut().setBody(response.getEntity());


On the client side, decode the response  

InputRepresentation representation = (InputRepresentation)resultEndpoint.getExchanges().get(0).getIn().getBody();
 Representation representationDecoded=  new DecodeRepresentation(representation);
String decodedString = representationDecoded.getText(); // will contain the decoded response




Reply | Threaded
Open this post in threaded view
|

Re: Camel-Restlet 2.14.0 DecodeRepresentation

Claus Ibsen-2
Hi

I think you are looking at some old code, the current code on master
does not match, and it seems as supporting using the representation
as-is.

I suggest to double check your findings.

On Fri, Nov 21, 2014 at 8:26 PM, sandp <[hidden email]> wrote:

> Looks like there's a bug in file*
> org.apache.camel.component.restlet.DefaultRestletBinding.java*
>
>
> *Method starts at line number 292*
> public void populateExchangeFromRestletResponse(Exchange exchange, Response
> response) throws Exception {
>         for (Map.Entry<String, Object> entry :
> response.getAttributes().entrySet()) {
>             String key = entry.getKey();
>             Object value = entry.getValue();
>             if (!headerFilterStrategy.applyFilterToExternalHeaders(key,
> value, exchange)) {
>                 exchange.getOut().setHeader(key, value);
>                 LOG.debug("Populate exchange from Restlet response header:
> {} value: {}", key, value);
>             }
>         }
>
>         // set response code
>         int responseCode = response.getStatus().getCode();
>         exchange.getOut().setHeader(Exchange.HTTP_RESPONSE_CODE,
> responseCode);
>
>         // set restlet response as header so end user have access to it if
> needed
>         exchange.getOut().setHeader(RestletConstants.RESTLET_RESPONSE,
> response);
>
>         if (response.getEntity() != null) {
>             // get content type
>             MediaType mediaType = response.getEntity().getMediaType();
>             if (mediaType != null) {
>                 LOG.debug("Setting the Content-Type to be {}",
> mediaType.toString());
>                 exchange.getOut().setHeader(Exchange.CONTENT_TYPE,
> mediaType.toString());
>             }
>             if (mediaType != null &&
> mediaType.equals(MediaType.APPLICATION_OCTET_STREAM)) {
>                 exchange.getOut().setBody(response.getEntity().getStream());
>             } *else {
>                 // get content text
>   Line 320              String text = response.getEntity().getText();
>   Line 321                 LOG.debug("Populate exchange from Restlet
> response: {}", text);
>   Line 322                 exchange.getOut().setBody(text);
>             }*
>         }
>
>         // preserve headers from in by copying any non existing headers
>         // to avoid overriding existing headers with old values
>         MessageHelper.copyHeaders(exchange.getIn(), exchange.getOut(),
> false);
>     }
>
> The bolded else part above gets the text from the entity in the Response and
> sets it on the OUT Message of the Exchange. But, at this point the
> response.getEntity() is of type InputRepresentation with MediaType.TEXT_XML
> and GZIP encoded, so why not pass the entity along as is? When its converted
> to a  String its tampered and lost (remember its encoded type is GZIP).
>
> *To make it work,* we could change the code to something like:
> replace lines 320 - 322 with
>   *exchange.getOut().setBody(response.getEntity());*
>
> *
> On the client side, decode the response  *
> InputRepresentation representation =
> (InputRepresentation)resultEndpoint.getExchanges().get(0).getIn().getBody();
>  Representation representationDecoded=  new
> DecodeRepresentation(representation);
> String decodedString = representationDecoded.getText(); // will contain the
> decoded response
>
>
>
>
>
>
>
>
> --
> View this message in context: http://camel.465427.n5.nabble.com/Camel-Restlet-2-14-0-DecodeRepresentation-tp5759382p5759484.html
> Sent from the Camel - Users mailing list archive at Nabble.com.



--
Claus Ibsen
-----------------
Red Hat, Inc.
Email: [hidden email]
Twitter: davsclaus
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen
hawtio: http://hawt.io/
fabric8: http://fabric8.io/
Reply | Threaded
Open this post in threaded view
|

Re: Camel-Restlet 2.14.0 DecodeRepresentation

sandp
Hi,
I just looked at the code on master https://github.com/apache/camel/blob/camel-2.14.x/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/DefaultRestletBinding.java

This code is different than the one in camel-restlet 2.14.0. Someone updated the file 5 days ago.

The method starts at line number 311 on Master . Below is the method from Master that I was talking about and it's the same as in  2.14.0

public void populateExchangeFromRestletResponse(Exchange exchange, Response response) throws Exception {
for (Map.Entry<String, Object> entry : response.getAttributes().entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (!headerFilterStrategy.applyFilterToExternalHeaders(key, value, exchange)) {
exchange.getOut().setHeader(key, value);
LOG.debug("Populate exchange from Restlet response header: {} value: {}", key, value);
}
}
// set response code
int responseCode = response.getStatus().getCode();
exchange.getOut().setHeader(Exchange.HTTP_RESPONSE_CODE, responseCode);
// set restlet response as header so end user have access to it if needed
exchange.getOut().setHeader(RestletConstants.RESTLET_RESPONSE, response);
if (response.getEntity() != null) {
// get content type
MediaType mediaType = response.getEntity().getMediaType();
if (mediaType != null) {
LOG.debug("Setting the Content-Type to be {}", mediaType.toString());
exchange.getOut().setHeader(Exchange.CONTENT_TYPE, mediaType.toString());
}
if (mediaType != null && mediaType.equals(MediaType.APPLICATION_OCTET_STREAM)) {
exchange.getOut().setBody(response.getEntity().getStream());
} else {
// get content text
String text = response.getEntity().getText();
LOG.debug("Populate exchange from Restlet response: {}", text);
exchange.getOut().setBody(text);
}

}
// preserve headers from in by copying any non existing headers
// to avoid overriding existing headers with old values
MessageHelper.copyHeaders(exchange.getIn(), exchange.getOut(), false);
}
Reply | Threaded
Open this post in threaded view
|

Re: Camel-Restlet 2.14.0 DecodeRepresentation

Willem.Jiang
Administrator
I think we could add a check point to verify if the entity is Representation and using DecodeRepresentation to decode the representation.

In this way the user can get the decoded text from the message body directly.

I just created a JIRA for it[1].

[1] https://issues.apache.org/jira/browse/CAMEL-8078 

--  
Willem Jiang

Red Hat, Inc.
Web: http://www.redhat.com
Blog: http://willemjiang.blogspot.com (English)
http://jnn.iteye.com (Chinese)
Twitter: willemjiang  
Weibo: 姜宁willem



On November 24, 2014 at 9:52:44 PM, sandp ([hidden email]) wrote:

> Hi,
> I just looked at the code on master
> https://github.com/apache/camel/blob/camel-2.14.x/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/DefaultRestletBinding.java 
>  
> This code is different than the one in camel-restlet 2.14.0. Someone updated
> the file 5 days ago.
>  
> *The method starts at line number 311 on Master *. Below is the method from
> Master that I was talking about and it's the same as in 2.14.0
>  
> public void populateExchangeFromRestletResponse(Exchange exchange, Response  
> response) throws Exception {
> for (Map.Entry entry : response.getAttributes().entrySet())
> {
> String key = entry.getKey();
> Object value = entry.getValue();
> if (!headerFilterStrategy.applyFilterToExternalHeaders(key, value,
> exchange)) {
> exchange.getOut().setHeader(key, value);
> LOG.debug("Populate exchange from Restlet response header: {} value: {}",
> key, value);
> }
> }
> // set response code
> int responseCode = response.getStatus().getCode();
> exchange.getOut().setHeader(Exchange.HTTP_RESPONSE_CODE, responseCode);
> // set restlet response as header so end user have access to it if needed
> exchange.getOut().setHeader(RestletConstants.RESTLET_RESPONSE, response);  
> if (response.getEntity() != null) {
> // get content type
> MediaType mediaType = response.getEntity().getMediaType();
> if (mediaType != null) {
> LOG.debug("Setting the Content-Type to be {}", mediaType.toString());
> exchange.getOut().setHeader(Exchange.CONTENT_TYPE, mediaType.toString());  
> }
> if (mediaType != null &&
> mediaType.equals(MediaType.APPLICATION_OCTET_STREAM)) {
> exchange.getOut().setBody(response.getEntity().getStream());
> }* else {
> // get content text
> String text = response.getEntity().getText();
> LOG.debug("Populate exchange from Restlet response: {}", text);
> exchange.getOut().setBody(text);
> }*
> }
> // preserve headers from in by copying any non existing headers
> // to avoid overriding existing headers with old values
> MessageHelper.copyHeaders(exchange.getIn(), exchange.getOut(), false);
> }
>  
>  
>  
>  
> --
> View this message in context: http://camel.465427.n5.nabble.com/Camel-Restlet-2-14-0-DecodeRepresentation-tp5759382p5759542.html 
> Sent from the Camel - Users mailing list archive at Nabble.com.
>