I tried building my own DF and that works (for me)

Jan


package org.apache.camel.dataformat;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import javax.activation.DataHandler;

import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.Processor;
import org.apache.camel.builder.ExchangeBuilder;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultMessage;
import org.apache.camel.spi.DataFormat;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.apache.camel.util.FileUtil;
import org.apache.commons.io.IOUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class SaveHeaderTest extends CamelTestSupport {
        
        private static File dataFile = new File("output/message.ser");
        
        DataFormat customDataFormat = new CustomDataFormat();
        
        @After
        @Before
        public void cleanup() {
                FileUtil.deleteFile(dataFile);
        }
        
        @SuppressWarnings("unchecked")
        @Test
        public void save() throws FileNotFoundException, Exception {
                File writtenTo = new File("output/message.ser");
                assertFalse(writtenTo.exists());
                Exchange exchange = ExchangeBuilder.anExchange(context)
                                .withBody("Hello World")
                                .withHeader("from", "Apache Camel")
                                .withHeader("test", "save")
                                .withHeader(Exchange.FILE_NAME,
"message.ser")
                                .build();
                template.send("direct:save", exchange);
                assertTrue(writtenTo.exists());

                // actual
                ObjectInputStream in = new ObjectInputStream(new
FileInputStream(dataFile));
                Object body = in.readObject();
                Map<String,Object> headers = (Map<String, Object>)
in.readObject();
                Map<String,DataHandler> attachments = (Map<String,
DataHandler>) in.readObject();
                String messageId = (String) in.readObject();
                boolean fault = (boolean) in.readObject();
                
                assertEquals("Hello World", body);
                assertEquals("Apache Camel", headers.get("from"));
                assertEquals("save", headers.get("test"));
                assertTrue(attachments.isEmpty());
                assertEquals(exchange.getIn().getMessageId(), messageId);
                assertFalse(fault);
        }
        
        @Test
        public void load() throws Exception {
                // create test data
                ObjectOutputStream out = new ObjectOutputStream(new
FileOutputStream(dataFile));
                out.writeObject("Hello World");
                
                Map<String,Object> headers = new HashMap<String, Object>();
                headers.put("from", "Apache Camel");
                headers.put("test", "load");
                out.writeObject(headers);
                
                Map<String,DataHandler> attachments = new
HashMap<String,DataHandler>();
                out.writeObject(attachments);
                
                out.writeObject("message-id");
                out.writeObject(false);
                out.close();
                
                // load the saved 'exchange'
                Exchange loadCommand = ExchangeBuilder.anExchange(context)
                                .withBody(dataFile.getAbsolutePath())
                                .build();
                Exchange response = template.send("direct:load",
loadCommand);
                assertEquals("Hello World",
response.getOut().getBody(String.class));
                assertEquals("Apache Camel",
response.getOut().getHeader("from"));
                assertEquals("load", response.getOut().getHeader("test"));
        }
        
        @Test
        public void turnaround() {
                Exchange exchange = ExchangeBuilder.anExchange(context)
                                .withBody("Hello World")
                                .withHeader("from", "Apache Camel")
                                .build();
                Exchange response = template.send("direct:turnaround",
exchange);
                assertEquals("Hello World",
response.getOut().getBody(String.class));
                assertEquals("Apache Camel",
response.getOut().getHeader("from"));
        }
        
        
        @Override
        protected RouteBuilder createRouteBuilder() throws Exception {
                return new RouteBuilder() {
                        @Override
                        public void configure() throws Exception {
                                from("direct:save")
                                        .marshal(customDataFormat)
                                        .to("file:output");
                                from("direct:load")
                                        .process(openFile())
                                        .unmarshal(customDataFormat);
                                from("direct:turnaround")
                                        .marshal(customDataFormat)
                                        .unmarshal(customDataFormat);
                        }

                        private Processor openFile() {
                                return new Processor() {
                                        @Override
                                        public void process(Exchange
exchange) throws Exception {
                                                String filename =
exchange.getIn().getBody(String.class);
                                                FileInputStream stream = new
FileInputStream(filename);
        
exchange.getIn().setBody(stream);
                                        }
                                };
                        }
                };
        }
        
        class CustomDataFormat implements DataFormat {
                
                @Override
                public void marshal(Exchange exchange, Object graph,
OutputStream stream)
                                throws Exception {
                        ObjectOutputStream out = null;
                        
                        try {
                                out = new ObjectOutputStream(stream);
                                // Save the body
                                out.writeObject(graph);
                                // Save the message
                                Message message = exchange.getIn();
                                if (message != null) {
                                        // Message is not serializable, so
save the data individually
        
out.writeObject(message.getHeaders());
        
out.writeObject(message.getAttachments());
        
out.writeObject(message.getMessageId());
                                        out.writeObject(message.isFault());
                                }
                        } finally {
                                IOUtils.closeQuietly(out);
                        }
                }

                @SuppressWarnings("unchecked")
                @Override
                public Object unmarshal(Exchange exchange, InputStream
stream)
                                throws Exception {
                        
                        ObjectInputStream in = null;
                        try {
                                in = new ObjectInputStream(stream);
                                
                                // read the raw data
                                Object body = in.readObject();
                                Map<String,Object> headers = (Map<String,
Object>) in.readObject();
                                Map<String,DataHandler> attachments =
(Map<String, DataHandler>) in.readObject();
                                String messageId = (String) in.readObject();
                                boolean fault = (boolean) in.readObject();
                                
                                // build the message
                                Message msg = new DefaultMessage();
                                msg.setBody(body);
                                msg.setAttachments(attachments);
                                msg.setHeaders(headers);
                                msg.setMessageId(messageId);
                                msg.setFault(fault);
                                
                                return msg;
                        } finally {
                                IOUtils.closeQuietly(in);
                        }
                }
        }
        
}

> -----Ursprüngliche Nachricht-----
> Von: Jan Matèrne (jhm) [mailto:apa...@materne.de]
> Gesendet: Donnerstag, 19. September 2013 07:06
> An: users@camel.apache.org
> Betreff: AW: How to set a header in custom DataFormat?
> 
> What I have found is, that the exchange object which is passed to the
> DataFormat is only used for getting the CamelContext.
> I searched a little bit further and found a processor for
> unmarshalling:
> 
> org.apache.camel.processor.UnmarshalProcessor.process(Exchange,
> AsyncCallback)
> 
> And there is a note
> 
>   Object result = dataFormat.unmarshal(exchange, stream);
>     if (result instanceof Exchange) {
>       if (result != exchange) {
>         // it's not allowed to return another exchange other than the
> one provided to dataFormat
>         throw new RuntimeCamelException("The returned exchange " +
> result + " is not the same as " + exchange + " provided to the
> DataFormat");
> 
> 
> The logic of that processor is:
> - get the object from the stream
> - if it is an exchange, throw that exception
> - if it is a message, store as 'out' on the exchange-parameter
> - if it is something else, store it as body of the 'out' message
> 
> 
> So have you tried setting the header on the 'out' message?
> 
> 
> Jan
> 
> 
> 
> > -----Ursprüngliche Nachricht-----
> > Von: Chris [mailto:cwolf.a...@gmail.com]
> > Gesendet: Mittwoch, 18. September 2013 22:58
> > An: users@camel.apache.org
> > Betreff: How to set a header in custom DataFormat?
> >
> > I implemented a custom DataFormat and in the "unmarshal(Exchange
> > exchange, InputStream stream)" implementation I set a header, but
> upon
> > attempting to retrieve the header downstream from the "unmarshal"
> > call, the header is not there.  Since the pattern is inOnly, I added
> > the header to the in Message.  I've done similar with custom
> > Processors and in that case, it works.  What is different with
> > DataFormat?  Is there any way to set header(s) from DataFormat
> marshal/unmarshal?
> >
> > Thanks,
> >
> > Chris


Reply via email to