/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.impl.transformer;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Map;
import org.apache.camel.AsyncCallback;
import org.apache.camel.Consumer;
import org.apache.camel.ContextTestSupport;
import org.apache.camel.Converter;
import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
import org.apache.camel.ExchangePattern;
import org.apache.camel.Message;
import org.apache.camel.Processor;
import org.apache.camel.Producer;
import org.apache.camel.TypeConverters;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.impl.DefaultAsyncProducer;
import org.apache.camel.impl.DefaultComponent;
import org.apache.camel.impl.DefaultEndpoint;
import org.apache.camel.impl.DefaultExchange;
import org.apache.camel.model.DataFormatDefinition;
import org.apache.camel.spi.DataFormat;
import org.apache.camel.spi.DataType;
import org.apache.camel.spi.DataTypeAware;
import org.apache.camel.spi.RouteContext;
import org.apache.camel.spi.Transformer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A TransformerTest demonstrates contract based declarative transformation via Java DSL.
*/
public class TransformerRouteTest extends ContextTestSupport {
protected static final Logger LOG = LoggerFactory.getLogger(TransformerRouteTest.class);
public void testJavaTransformer() throws Exception {
MockEndpoint abcresult = getMockEndpoint("mock:abcresult");
abcresult.expectedMessageCount(1);
abcresult.whenAnyExchangeReceived(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
LOG.info("Asserting String -> XOrderResponse convertion");
assertEquals(XOrderResponse.class, exchange.getIn().getBody().getClass());
}
});
MockEndpoint xyzresult = getMockEndpoint("mock:xyzresult");
xyzresult.expectedMessageCount(1);
xyzresult.whenAnyExchangeReceived(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
LOG.info("Asserting String -> XOrderResponse convertion is not yet performed");
assertEquals("response", exchange.getIn().getBody());
}
});
Exchange exchange = new DefaultExchange(context, ExchangePattern.InOut);
exchange.getIn().setBody(new AOrder());
Exchange answerEx = template.send("direct:abc", exchange);
if (answerEx.getException() != null) {
throw answerEx.getException();
}
assertEquals(AOrderResponse.class, answerEx.getOut().getBody().getClass());
assertMockEndpointsSatisfied();
}
public void testDataFormatTransformer() throws Exception {
MockEndpoint xyzresult = getMockEndpoint("mock:xyzresult");
xyzresult.expectedMessageCount(1);
xyzresult.whenAnyExchangeReceived(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
LOG.info("Asserting String -> XOrderResponse convertion is not yet performed");
assertEquals("response", exchange.getIn().getBody());
}
});
Exchange exchange = new DefaultExchange(context, ExchangePattern.InOut);
((DataTypeAware)exchange.getIn()).setBody("{name:XOrder}", new DataType("json:JsonXOrder"));
Exchange answerEx = template.send("direct:dataFormat", exchange);
if (answerEx.getException() != null) {
throw answerEx.getException();
}
assertEquals("{name:XOrderResponse}", answerEx.getOut().getBody(String.class));
assertMockEndpointsSatisfied();
}
public void testEndpointTransformer() throws Exception {
MockEndpoint xyzresult = getMockEndpoint("mock:xyzresult");
xyzresult.expectedMessageCount(1);
xyzresult.whenAnyExchangeReceived(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
LOG.info("Asserting String -> XOrderResponse convertion is not yet performed");
assertEquals("response", exchange.getIn().getBody());
}
});
Exchange exchange = new DefaultExchange(context, ExchangePattern.InOut);
exchange.getIn().setBody("<XOrder/>");
Exchange answerEx = template.send("direct:endpoint", exchange);
if (answerEx.getException() != null) {
throw answerEx.getException();
}
assertEquals("<XOrderResponse/>", answerEx.getOut().getBody(String.class));
assertMockEndpointsSatisfied();
}
public void testCustomTransformer() throws Exception {
MockEndpoint xyzresult = getMockEndpoint("mock:xyzresult");
xyzresult.expectedMessageCount(1);
xyzresult.whenAnyExchangeReceived(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
LOG.info("Asserting String -> XOrderResponse convertion is not yet performed");
assertEquals("response", exchange.getIn().getBody());
}
});
Exchange exchange = new DefaultExchange(context, ExchangePattern.InOut);
exchange.getIn().setBody("name=XOrder");
Exchange answerEx = template.send("direct:custom", exchange);
if (answerEx.getException() != null) {
throw answerEx.getException();
}
assertEquals("name=XOrderResponse", answerEx.getOut().getBody(String.class));
assertMockEndpointsSatisfied();
}
@Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
context.getTypeConverterRegistry().addTypeConverters(new MyTypeConverters());
from("direct:abc")
.inputType(AOrder.class)
.outputType(AOrderResponse.class)
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
LOG.info("Asserting input -> AOrder convertion");
assertEquals(AOrder.class, exchange.getIn().getBody().getClass());
}
})
.inOut("direct:xyz")
.to("mock:abcresult");
from("direct:xyz")
.inputType(XOrder.class)
.outputType(XOrderResponse.class)
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
LOG.info("Asserting input -> XOrder convertion");
assertEquals(XOrder.class, exchange.getIn().getBody().getClass());
exchange.getIn().setBody("response");
}
}).to("mock:xyzresult");
transformer()
.scheme("json")
.withDataFormat(new MyJsonDataFormatDefinition());
from("direct:dataFormat")
.inputType("json:JsonXOrder")
.outputType("json:JsonXOrderResponse")
.inOut("direct:xyz");
context.addComponent("myxml", new MyXmlComponent());
transformer()
.fromType("xml:XmlXOrder")
.toType(XOrder.class)
.withUri("myxml:endpoint");
transformer()
.fromType(XOrderResponse.class)
.toType("xml:XmlXOrderResponse")
.withUri("myxml:endpoint");
from("direct:endpoint")
.inputType("xml:XmlXOrder")
.outputType("xml:XmlXOrderResponse")
.inOut("direct:xyz");
transformer()
.fromType("other:OtherXOrder")
.toType(XOrder.class)
.withJava(OtherToXOrderTransformer.class);
transformer()
.fromType(XOrderResponse.class)
.toType("other:OtherXOrderResponse")
.withJava(XOrderResponseToOtherTransformer.class);
from("direct:custom")
.inputType("other:OtherXOrder")
.outputType("other:OtherXOrderResponse")
.inOut("direct:xyz");
}
};
}
public static class MyTypeConverters implements TypeConverters {
@Converter
public AOrder toAOrder(String order) {
LOG.info("TypeConverter: String -> AOrder");
return new AOrder();
}
@Converter
public XOrder toXOrder(AOrder aorder) {
LOG.info("TypeConverter: AOrder -> XOrder");
return new XOrder();
}
@Converter
public XOrderResponse toXOrderResponse(String res) {
LOG.info("TypeConverter: String -> XOrderResponse");
return new XOrderResponse();
}
@Converter
public AOrderResponse toAOrderResponse(XOrderResponse xres) {
LOG.info("TypeConverter: XOrderResponse -> AOrderResponse");
return new AOrderResponse();
}
}
public static class MyJsonDataFormatDefinition extends DataFormatDefinition {
public static DataFormat getDataFormat(RouteContext routeContext, DataFormatDefinition type, String ref) {
return new MyJsonDataFormatDefinition().createDataFormat();
}
public DataFormat getDataFormat(RouteContext routeContext) {
return createDataFormat();
}
private DataFormat createDataFormat() {
return new DataFormat() {
@Override
public void marshal(Exchange exchange, Object graph, OutputStream stream) throws Exception {
assertEquals(graph.toString(), XOrderResponse.class, graph.getClass());
LOG.info("DataFormat: XOrderResponse -> JSON");
stream.write("{name:XOrderResponse}".getBytes());
}
@Override
public Object unmarshal(Exchange exchange, InputStream stream) throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String line = "";
String input = "";
while ((line = reader.readLine()) != null) {
input += line;
}
reader.close();
assertEquals("{name:XOrder}", input);
LOG.info("DataFormat: JSON -> XOrder");
return new XOrder();
}
};
}
}
public static class MyXmlComponent extends DefaultComponent {
@Override
protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
return new MyXmlEndpoint();
}
}
public static class MyXmlEndpoint extends DefaultEndpoint {
@Override
public Producer createProducer() throws Exception {
return new DefaultAsyncProducer(this) {
@Override
public boolean process(Exchange exchange, AsyncCallback callback) {
Object input = exchange.getIn().getBody();
if (input instanceof XOrderResponse) {
LOG.info("Endpoint: XOrderResponse -> XML");
exchange.getIn().setBody("<XOrderResponse/>");
} else {
assertEquals("<XOrder/>", input);
LOG.info("Endpoint: XML -> XOrder");
exchange.getIn().setBody(new XOrder());
}
callback.done(true);
return true;
}
};
}
@Override
public Consumer createConsumer(Processor processor) throws Exception {
return null;
}
@Override
public boolean isSingleton() {
return false;
}
@Override
protected String createEndpointUri() {
return "myxml:endpoint";
}
}
public static class OtherToXOrderTransformer extends Transformer {
@Override
public void transform(Message message, DataType from, DataType to) throws Exception {
assertEquals("name=XOrder", message.getBody());
LOG.info("Bean: Other -> XOrder");
message.setBody(new XOrder());
}
}
public static class XOrderResponseToOtherTransformer extends Transformer {
@Override
public void transform(Message message, DataType from, DataType to) throws Exception {
LOG.info("Bean: XOrderResponse -> Other");
message.setBody("name=XOrderResponse");
}
}
public static class AOrder { }
public static class AOrderResponse { }
public static class XOrder { }
public static class XOrderResponse { }
}