Logger logger = Logger.getLogger(ThrowsLoggingAdvice.class);
public void afterThrowing(Method method, Object[] arguments, Object target, BatchException ex) throws Throwable {
BatchException batchException=ex;
Logger.getLogger(target.getClass()).debug("afterThrowing: BatchException");
logger.error(ex.getMessage());
}
Related
I have a flink program with source from kafka, and i opened three windowedStream:seconds, minutes,hours.Then sending window result to others by AsyncHttpSink extends RichSinkFunction.But i found that same window,one kafka message, same result may invoke AsyncHttpSink.invoke() function multiple times which aroused my curiosity.Shouldn't it happen just once in same window,one kafka message, same result?
hourOperator.addSink(httpSink(WindowType.h));
minuteOperator.addSink(httpSink(WindowType.m));
secondOperator.addSink(httpSink(WindowType.s));
/**
* http sink
*/
public class AsyncHttpSink extends RichSinkFunction<Tuple3<String, Long, Map<String, Tuple2<XXX, Object>>>> {
public AsyncHttpSink(WindowType windowType) {
this.windowType = windowType;
}
#Override
public void open(Configuration parameters) throws Exception {
httpClient = HttpAsyncClients.custom()
.build();
httpClient.start();
}
#Override
public void close() throws Exception {
httpClient.close();
}
#Override
public void invoke(Tuple3<String, Long, Map<String, Tuple2<XXX, Object>>> tuple3, Context context) throws Exception {
httpClient.execute(httpPost, new FutureCallback<HttpResponse>() {
#Override
public void completed(HttpResponse response) {
try {
logger.info("[httpSink]http sink completed.");
} catch (IOException e) {
logger.error("[httpSink]http sink completed. exception:", e);
}
}
#Override
public void failed(Exception ex) {
logger.error("[httpSink]http sink failed.", ex);
}
#Override
public void cancelled() {
logger.info("[httpSink]http sink cancelled.");
}
});
}
}
If this is a keyed window, then each distinct key that has results for a given window will report its results separately.
And you may have several parallel instances of the sink.
I have written camel test case for my spring boot application as below.
#RunWith(CamelSpringRunner.class)
#SpringBootTest
#ActiveProfiles("test")
#ContextConfiguration(classes = Application.class)
#DirtiesContext(classMode = AFTER_EACH_TEST_METHOD)
#UseAdviceWith
public class CamelTestClass {
#Autowired
private CamelContext camelContext;
private String routeID = "routeId";
Logger log = Logger.getLogger(String.valueOf(CamelSpringBootApplication.class));
#Test
#DirtiesContext
public void test1() throws Exception {
ModelCamelContext mcc = camelContext.adapt(ModelCamelContext.class);
RouteReifier.adviceWith(mcc.getRouteDefinition(routeID), mcc, new AdviceWithRouteBuilder() {
#Override
public void configure() throws Exception {
doSOmething
}
});
mcc.start();
assertion
mcc.stop();
}
#Test
#DirtiesContext
public void test2() throws Exception {
ModelCamelContext mcc = camelContext.adapt(ModelCamelContext.class);
RouteReifier.adviceWith(mcc.getRouteDefinition(routeID), mcc, new AdviceWithRouteBuilder() {
#Override
public void configure() throws Exception {
doSomething
}
});
mcc.start();
assertion
mcc.stop();
}
#Test
#DirtiesContext
public void test3() throws Exception {
ModelCamelContext mcc = camelContext.adapt(ModelCamelContext.class);
RouteReifier.adviceWith(mcc.getRouteDefinition(routeID), mcc, new AdviceWithRouteBuilder() {
#Override
public void configure() throws Exception {
doSomething
}
});
mcc.start();
assertion
mcc.stop();
}
}
So there are 3 test cases written, On each beginning of the test case I had to start the camel context and clear it at the end. With this setup, On a maven build test tests are taking a long time to get it completed. with around 30 test cases, the build is taking 25 mins for completion. Is there a scope for optimization of test cases in terms of running time here?
I am trying to hit a REST endpoint on Camel and convert that data into a class (and for simplicity and testing convert that class into a JSON string) and make a POST to a local server. I can get it to do all but make that final post and just seems to hang.
App:
#SpringBootApplication
public class App {
/**
* A main method to start this application.
*/
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
#Component
public class RestTest extends RouteBuilder {
#Override
public void configure() throws Exception {
restConfiguration().component("restlet").host("localhost").port(8000).bindingMode(RestBindingMode.json);
rest("/test").enableCORS(true)
.post("/post").type(User.class).to("direct:transform");
from("direct:transform")
.transform().method("Test", "alter")
.to("http4:/localhost:8088/ws/v1/camel");
}
}
}
Bean:
#Component("Test")
public class Test {
public void alter (Exchange exchange) {
ObjectMapper mapper = new ObjectMapper();
User body = exchange.getIn().getBody(User.class);
try {
String jsonInString = mapper.writeValueAsString(body);
exchange.getOut().setHeader(Exchange.HTTP_METHOD, constant(HttpMethods.POST));
exchange.getOut().setHeader(Exchange.CONTENT_TYPE, MediaType.APPLICATION_JSON);
exchange.getOut().setBody(jsonInString);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
User:
public class User {
#JsonProperty
private String firstName;
#JsonProperty
private String lastName;
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getLastName() {
return lastName;
}
}
UPDATE
Able to get it to work with process instead of transform but errors when a response is sent back to Camel from the POST:
from("direct:transform")
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
ObjectMapper mapper = new ObjectMapper();
User body = exchange.getIn().getBody(User.class);
try {
String jsonInString = mapper.writeValueAsString(body);
exchange.getOut().setHeader(Exchange.HTTP_METHOD, constant(HttpMethods.POST));
exchange.getOut().setHeader(Exchange.CONTENT_TYPE, MediaType.APPLICATION_JSON);
exchange.getOut().setBody(jsonInString);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
})
.to("http4://0.0.0.0:8088/ws/v1/camel");
Error
com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.apache.camel.converter.stream.CachedOutputStream$WrappedInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:284)
at com.fasterxml.jackson.databind.SerializerProvider.mappingException(SerializerProvider.java:1110)
at com.fasterxml.jackson.databind.SerializerProvider.reportMappingProblem(SerializerProvider.java:1135)
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:69)
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:32)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:292)
at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1429)
at com.fasterxml.jackson.databind.ObjectWriter._configAndWriteValue(ObjectWriter.java:1158)
at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:988)
at org.apache.camel.component.jackson.JacksonDataFormat.marshal(JacksonDataFormat.java:155)
at org.apache.camel.processor.MarshalProcessor.process(MarshalProcessor.java:69)
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:109)
at org.apache.camel.processor.MarshalProcessor.process(MarshalProcessor.java:50)
at org.apache.camel.component.rest.RestConsumerBindingProcessor$RestConsumerBindingMarshalOnCompletion.onAfterRoute(RestConsumerBindingProcessor.java:363)
at org.apache.camel.util.UnitOfWorkHelper.afterRouteSynchronizations(UnitOfWorkHelper.java:154)
at org.apache.camel.impl.DefaultUnitOfWork.afterRoute(DefaultUnitOfWork.java:278)
at org.apache.camel.processor.CamelInternalProcessor$RouteLifecycleAdvice.after(CamelInternalProcessor.java:317)
at org.apache.camel.processor.CamelInternalProcessor$InternalCallback.done(CamelInternalProcessor.java:246)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:109)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:197)
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:97)
at org.apache.camel.component.restlet.RestletConsumer$1.handle(RestletConsumer.java:68)
at org.apache.camel.component.restlet.MethodBasedRouter.handle(MethodBasedRouter.java:54)
at org.restlet.routing.Filter.doHandle(Filter.java:150)
at org.restlet.routing.Filter.handle(Filter.java:197)
at org.restlet.routing.Router.doHandle(Router.java:422)
at org.restlet.routing.Router.handle(Router.java:639)
at org.restlet.routing.Filter.doHandle(Filter.java:150)
at org.restlet.routing.Filter.handle(Filter.java:197)
at org.restlet.routing.Router.doHandle(Router.java:422)
at org.restlet.routing.Router.handle(Router.java:639)
at org.restlet.routing.Filter.doHandle(Filter.java:150)
at org.restlet.engine.application.StatusFilter.doHandle(StatusFilter.java:140)
at org.restlet.routing.Filter.handle(Filter.java:197)
at org.restlet.routing.Filter.doHandle(Filter.java:150)
at org.restlet.routing.Filter.handle(Filter.java:197)
at org.restlet.engine.CompositeHelper.handle(CompositeHelper.java:202)
at org.restlet.Component.handle(Component.java:408)
at org.restlet.Server.handle(Server.java:507)
at org.restlet.engine.connector.ServerHelper.handle(ServerHelper.java:63)
at org.restlet.engine.adapter.HttpServerHelper.handle(HttpServerHelper.java:143)
at org.restlet.engine.connector.HttpServerHelper$1.handle(HttpServerHelper.java:64)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79)
at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:83)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:82)
at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:675)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79)
at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:647)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Leading to the question of what is the fundamental difference between process and transform?
A "Processor" in camel is the lowest level message processing primitive. Under the covers a transform definition is executed as a org.apache.camel.processor.TransformProcessor which is itself a processor. In fact mostly everything is a Processor under the hood so strictly anything you can accomplish with transform you can accomplish with a pure processor:
Your last error is because you need to unmarshal the output of your HTTP call to an object, before it can be marshalled back to JSON using Jackson. Something like that:
from("direct:transform")
.transform().method("Test", "alter")
.to("http4:/localhost:8088/ws/v1/camel")
.unmarshal().json(JsonLibrary.Jackson, User.class);
I am trying to test a Camel route (polling messages from an SQS queue) containing
.bean("messageParserProcessor")
where messageParserProcessor is a Processor.
The test:
public class SomeTest extends CamelTestSupport {
private final String queueName = ...;
private final String producerTemplateUri = "aws-sqs://" + queueName + ...;
private static final String MESSAGE_PARSER_PROCESSOR_MOCK_ENDPOINT = "mock:messageParserProcessor";
#EndpointInject(uri = MESSAGE_PARSER_PROCESSOR_MOCK_ENDPOINT)
protected MockEndpoint messageParserProcessor;
#Override
public boolean isUseAdviceWith() {
return true;
}
#Before
public void setUpContext() throws Exception {
context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() {
#Override
public void configure() throws Exception {
interceptSendToEndpoint("bean:messageParserProcessor")
.skipSendToOriginalEndpoint()
.process(MESSAGE_PARSER_PROCESSOR_MOCK_ENDPOINT);
}
});
}
#Test
public void testParser() throws Exception {
context.start();
String expectedBody = "test";
messageParserProcessor.expectedBodiesReceived(expectedBody);
ProducerTemplate template = context.createProducerTemplate();
template.sendBody(producerTemplateUri, expectedBody);
messageParserProcessor.assertIsSatisfied();
context.stop();
}
}
When I run the test I get this error:
org.apache.camel.FailedToCreateRouteException:
Failed to create route route1 at:
>>> InterceptSendToEndpoint[bean:messageParserProcessor -> [process[ref:mock:messageParserProcessor]]] <<< in route: Route(route1)[[From[aws-sqs://xxx...
because of No bean could be found in the registry for: mock:messageParserProcessor of type: org.apache.camel.Processor
Same error if I replace interceptSendToEndpoint(...) with mockEndpointsAndSkip("bean:messageParserProcessor")
The test can be executed (but obviously doesn't pass) when I don't use a mock:
interceptSendToEndpoint("bean:messageParserProcessor")
.skipSendToOriginalEndpoint()
.process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception {}
});
So the problem is the mock that is not found, what is wrong in the way I create it?
So I found a workaround to retrieve mocks from the registry:
interceptSendToEndpoint("bean:messageParserProcessor")
.skipSendToOriginalEndpoint()
.bean(getMockEndpoint(MESSAGE_PARSER_PROCESSOR_MOCK_ENDPOINT));
// Instead of
// .process(MESSAGE_PARSER_PROCESSOR_MOCK_ENDPOINT);
But I still don't understand why using .process("mock:someBean") doesn't work...
i'm newbie with apache camel (I'm using 2.8.1 version). I'm working with this framework and i understand (i hope) concept like route. Now i have this route definition
try {
context.addRoutes(new RouteBuilder() {
#Override
public void configure() throws Exception {
// TODO Auto-generated method stub
from("vm:internal").
split().method(DefaultSplitLogic.class, "split").
dynamicRouter(bean(router, "route"));
}
});
}catch (DefaultSplitLogicException e) {
// TODO: handle exception
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
This is the DefaultSpliLogic.class
public class DefaultSplitLogic {
public Object[] split(Object o) throws DefaultSplitLogicException{
if(o instanceof Collection<?>){
Collection c = (Collection) o;
return c.toArray();
}
else {
throw new DefaultSplitLogicException("Default Splitting Logic not correct");
}
}
}
This is DefaultSplitLogicException.class
public class DefaultSplitLogicException extends Exception{
/**
*
*/
private static final long serialVersionUID = 1L;
public DefaultSplitLogicException(String msg) {
// TODO Auto-generated constructor stub
super(msg);
System.err.println(msg);
}
public DefaultSplitLogicException(Throwable cause) {
super(cause);
}
}
I leaved router definition.
Now i want to capture my exception (i'm sure that my exception is thrown).
I'm using the onException clause into the route definition
try {
context.addRoutes(new RouteBuilder() {
#Override
public void configure() throws Exception {
// TODO Auto-generated method stub
onException(DefaultSplitLogicException.class).handled(false);
from("vm:internal").
split().method(DefaultSplitLogic.class, "split").
dynamicRouter(bean(router, "route"));
}
});
}catch (DefaultSplitLogicException e) {
// TODO: handle exception
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
but i cannot manage my exception. I tried to use differently this clause without success. Why?
Thank you all
I think i found the answer. It should be a bug of 2.8.1. version, fixed with 2.8.2+
http://camel.465427.n5.nabble.com/Cannot-handle-Exception-thrown-from-Splitter-Expression-td3286043.html