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.

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 :)


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/
>


Reply via email to