The marshaler approach is perfect, If only the component wouldn't try to
forward the message every time and let me handle the "sendOut" method where
there is no specified targetService/targetInterface that would solve it. I
guess I could have tried putting a dummy loopback service in targetService
and I would have gotten to the sendOut method without error, but what if I
don't want it to forward? hmm... :)


Eduardo Burgos


On 3/20/07, Guillaume Nodet <[EMAIL PROTECTED]> wrote:

On 3/20/07, Eduardo Burgos <[EMAIL PROTECTED]> wrote:
>
> Ok, this is how I did it, however I don't feel very comfortable with it.
>
> First I created a HttpConsumerMarshaler and I read the path from the
> HttpConsumerEndpoint's "targetUri" property.
>
> I couldnt get the "endpoint" field from the EndpointComponentContext, so
I
> had to reflect :(, why isnt that method public by the way?
> EndpointComponentContext.getEndpoint() { return endpoint; } would be
nice.


Done

I used this on servicemix.xml:
>
> <http:consumer service="foo:ImageLoad"
> >                          endpoint="endpoint"
> >                          marshaler="#imageLoadMarshaler"
> >                          authMethod="basic"
> >                          locationURI="http://0.0.0.0:8004/getImage";
>
>                          targetUri="classpath:com/foo/package/image.jpg"
> >                          defaultMep="
> http://www.w3.org/2004/08/wsdl/in-out";
> > />
> >
>
> At this point, #imageLoadMarshaler is an instance of my
> HttpConsumerMarshaler, and targetUri has my file resource that I want to
> publish.
>
> The other issue I had is, since I'm not interested in forwarding the
> message, I have no targetService property set and the targetUri has
> nothing
> to do with forwarding either, so I always get a no route exception,
which
> led me to implement the logic in the sendError() method :(. Is it
possible
> that the component doesn't forward if there is no
> targetService,targetEndpoint, etc?
>
> Also, I was looking at the HttpConsumerEndpoint and I saw a "resources"
> map
> that had to do with the "handleStaticResource" method. At the end (line
> 331)
> in "else if (res != null) " the method throws an exception for being
> unable
> to serialize. If that method could also test for a "
> org.springframework.core.io.Resource" instance or something similar and
> pass
> it on through the response that would have solved the problem without a
> custom marshaler.
>
>
> This is my marshaler code, it worked very well, but I hope that there is
> another way :)


Yeah, I agree we need to find a better way to do that.
I think we could either
  *  allow the marshaler to handle static resources
  * implement a new consumer endpoint which would not really use any
marshaler, but
     just serve static resources

package org.inovaware.mokala.jbi.http;
> >
> > import java.io.BufferedInputStream;
> > import java.io.PrintWriter;
> > import java.io.StringWriter;
> > import java.lang.reflect.Field;
> > import java.net.URI;
> >
> > import javax.jbi.component.ComponentContext;
> > import javax.jbi.messaging.Fault;
> > import javax.jbi.messaging.MessageExchange;
> > import javax.jbi.messaging.NormalizedMessage;
> > import javax.servlet.http.HttpServletRequest;
> > import javax.servlet.http.HttpServletResponse;
> > import javax.xml.stream.XMLStreamReader;
> > import javax.xml.stream.XMLStreamWriter;
> > import javax.xml.transform.stream.StreamSource;
> >
> > import org.apache.servicemix.common.EndpointComponentContext;
> > import org.apache.servicemix.http.endpoints.HttpConsumerEndpoint;
> > import org.apache.servicemix.http.endpoints.HttpConsumerMarshaler;
> > import org.apache.servicemix.jbi.jaxp.StAXSourceTransformer;
> > import org.apache.servicemix.jbi.jaxp.XMLStreamHelper;
> > import org.apache.servicemix.jbi.messaging.MessageExchangeSupport;
> > import org.springframework.core.io.ClassPathResource;
> > import org.springframework.core.io.FileSystemResource;
> > import org.springframework.core.io.Resource;
> >
> > public class FileURIConsumerMarshaler implements HttpConsumerMarshaler
{
> >
> >     private StAXSourceTransformer transformer = new
> > StAXSourceTransformer();
> >
> >     private URI defaultMep;
> >
> >     public FileURIConsumerMarshaler() {
> >         this(MessageExchangeSupport.IN_OUT);
> >     }
> >
> >     public FileURIConsumerMarshaler(URI defaultMep) {
> >         this.defaultMep = defaultMep;
> >     }
> >
> >     public MessageExchange createExchange(HttpServletRequest request,
> >             ComponentContext context) throws Exception {
> >         MessageExchange me;
> >         me = context.getDeliveryChannel().createExchangeFactory()
> >                 .createExchange(getDefaultMep());
> >         NormalizedMessage in = me.createMessage();
> >         in.setContent(new StreamSource(request.getInputStream()));
> >         me.setMessage(in, "in");
> >
> >         in.setProperty("context", context);
> >         return me;
> >     }
> >
> >     public void sendOut(MessageExchange exchange, NormalizedMessage
> > outMsg,
> >             HttpServletRequest request, HttpServletResponse response)
> >             throws Exception {
> >
> >     }
> >
> >     public void sendFault(MessageExchange exchange, Fault fault,
> >             HttpServletRequest request, HttpServletResponse response)
> >             throws Exception {
> >         response.setStatus(
HttpServletResponse.SC_INTERNAL_SERVER_ERROR
> );
> >         XMLStreamReader reader = transformer.toXMLStreamReader(fault
> >                 .getContent());
> >         XMLStreamWriter writer = transformer.getOutputFactory()
> >                 .createXMLStreamWriter(response.getWriter());
> >         XMLStreamHelper.copy(reader, writer);
> >     }
> >
> >     public void sendError(MessageExchange exchange, Exception error,
> >             HttpServletRequest request, HttpServletResponse response)
> >             throws Exception {
> >
> >         // this means success :(
> >         if (error.getMessage().startsWith("Could not find route for
> > exchange")) {
> >
> >             String source = "";
> >             EndpointComponentContext ctx = (EndpointComponentContext)
> > exchange.getMessage("in").getProperty("context");
> >             Field f = ctx.getClass().getDeclaredField("endpoint");
> >             boolean wasAccessible = f.isAccessible();
> >             if (!wasAccessible)
> >             {
> >                 f.setAccessible(true);
> >             }
> >             HttpConsumerEndpoint httpe = (HttpConsumerEndpoint) f.get
> > (ctx);
> >             f.setAccessible(wasAccessible);
> >             source = httpe.getTargetUri();
> >
> >
> >
> >             response.setHeader("Content-Disposition", "inline");
> >             response.addHeader("Content-Transfer-Encoding", "Binary");
> >
> >             Resource r = null;
> >
> >             if (source.toString().startsWith("classpath:")) {
> >                 String res = source.toString().substring(10);
> >
> >                 r = new ClassPathResource(res);
> >             } else {
> >                 r = new FileSystemResource(source.toString());
> >             }
> >
> >
> >
> >
> >             if ("jpg".equals(source.toString().substring(
> source.toString
> > ().lastIndexOf('.')+1)))
> >             {
> >                 response.setContentType("image/jpeg");
> >             }
> >             else if ("xml".equals(source.toString().substring(
> > source.toString().lastIndexOf('.')+1)))
> >             {
> >                 response.setContentType("text/xml");
> >             }
> >             else
> >             {
> >                 response.setContentType("application/binary");
> >             }
> >
> >             if (r != null) {
> >
> >                 BufferedInputStream istr = new BufferedInputStream(r
> >                         .getInputStream(), 1000);
> >
> >                 byte[] buff = new byte[1000];
> >
> >                 int s = 0;
> >                 while ((s = istr.read(buff)) > 0) {
> >                     response.getOutputStream().write(buff, 0, s);
> >                 }
> >                 istr.close();
> >
> >                 response.getOutputStream().close();
> >
> >                 response.setStatus(HttpServletResponse.SC_OK);
> >
> >             } else {
> >                 response.setStatus(404);
> >             }
> >         } else {
> >
> >             response.setStatus(
> > HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
> >             XMLStreamWriter writer = transformer.getOutputFactory()
> >                     .createXMLStreamWriter(response.getWriter());
> >             writer.writeStartDocument();
> >             writer.writeStartElement("error");
> >             StringWriter sw = new StringWriter();
> >             PrintWriter pw = new PrintWriter(sw);
> >             error.printStackTrace(pw);
> >             pw.close();
> >             writer.writeCData(sw.toString());
> >             writer.writeEndElement();
> >             writer.writeEndDocument();
> >         }
> >     }
> >
> >     public void sendAccepted(MessageExchange exchange,
> >             HttpServletRequest request, HttpServletResponse response)
> >             throws Exception {
> >         response.setStatus(HttpServletResponse.SC_ACCEPTED);
> >     }
> >
> >     public URI getDefaultMep() {
> >         return defaultMep;
> >     }
> >
> >     public void setDefaultMep(URI defaultMep) {
> >         this.defaultMep = defaultMep;
> >     }
> > }
>
>
>
>
>
>
>
> Eduardo Burgos
>
>
>
>
>
>
>
>
>
>
> On 3/2/07, Eduardo Burgos <[EMAIL PROTECTED]> wrote:
> >
> > Ok, I'll try to do it myself and post on this thread.
> >
> >
> >
> > On 2/28/07, Guillaume Nodet <[EMAIL PROTECTED] > wrote:
> > >
> > > There's no way to do that out of the box.
> > > I would try hacking one of the lightweight http component
> > > to support that.
> > > Or you could try with the new marshaler stuff that we are working
> > > on in servicemix-http (in the
> org.apache.servicemix.http.endpointspackage).
> > >
> > > On 2/26/07, Eduardo Burgos < [EMAIL PROTECTED]> wrote:
> > > > is there a way were I can expose file endpoints via http? i.e., I
> want
> > > to
> > > > have something like http://localhost/info.pdf point to a pdf
> document
> > > in my
> > > > filesystem. How can I do this with servicemix-http? or is there
> > > another way
> > > > to do it?
> > > >
> > >
> > >
> > > --
> > > Cheers,
> > > Guillaume Nodet
> > > ------------------------
> > > Architect, LogicBlaze ( http://www.logicblaze.com/)
> > > Blog: http://gnodet.blogspot.com/
> > >
> >
> >
>



--
Cheers,
Guillaume Nodet
------------------------
Architect, LogicBlaze (http://www.logicblaze.com/)
Blog: http://gnodet.blogspot.com/

Reply via email to