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