2014-05-19 5 views
5

मेरे पास एक बहुत ही सरल ऊंट मार्ग परिभाषा है जिसमें कुछ ऑनएक्सप्शन शामिल हैं जो संबंधित अपवादों और कुछ लॉग-स्टेटमेंट को संभालने के लिए भविष्यवाणी करते हैं।सलाह का उपयोग कर ऊंट मार्ग-परीक्षण ऑनएक्सप्शन परिभाषाओं के साथ

from("hazelcast:seda:someQueue") 
    .id("someQueueID") 
    .onException(CustomException.class) 
     .handled(true) 
     .log(LoggingLevel.WARN, "custom exception noticed") 
    .end() 
    .onException(IOException.class, FileNotFoundException.class) 
     .asyncDelayedRedelivery() 
     .redeliveryDelay(3*1000*60) // 3 Minutes 
     .maximumRedeliveries(3) 
     .log(LoggingLevel.WARN, "io exception noticed") 
    .end() 
    .onException(Exception.class) 
     .log(LoggingLevel.WARN, "general exception noticed") 
    .end() 

    .log("Starting route") 
    .bean(TestBean.class) 
    .log("Finished route"); 

सेम ही सरल भी, यह सिर्फ एक हैडर पैरामीटर की जांच करता है और एक उचित अपवाद

public class TestBean 
{ 
    @Handler 
    public void checkData(@Headers final Map<String, Object> headers) 
      throws CustomException, IOException, Exception 
    { 
     Integer testVal = (Integer)headers.get("TestValue"); 
     if (0 == testVal) 
      throw new CustomException("CustomException"); 
     else if (1 == testVal) 
      throw new IOException("IOException"); 
     else 
      throw new Exception("Exception"); 
    } 
} 

फेंकता के रूप में इस परीक्षण सेटअप सिर्फ एक बड़ी परियोजना के एक छोटे से हिस्से में यह मूर्खतापूर्ण लग सकता है ऐसा प्रस्तुत करने के लिए यहां प्रस्तुत करने के लिए, लेकिन मुख्य इरादा पुनर्वितरण को संशोधित करना है "परीक्षण" के रूप में परीक्षण समय पर IOException को 3 मिनट तक इंतजार करने की आवश्यकता नहीं होगी और इसलिए यूनिट परीक्षणों को थोड़ा तेज़ करने के लिए, पुनर्विक्रय विलंब को कम किया जा सकता है 10 एमएस की तरह

आदेश यह मेरा परीक्षण विधि प्राप्त करने के लिए करता है निम्नलिखित:

@ContextConfiguration(classes = OnExceptionRouteTest.ContextConfig.class, loader = AnnotationConfigContextLoader.class) 
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) 
public class OnExceptionRouteTest extends CamelSpringTestSupport 
{ 
    @Override 
    protected AbstractApplicationContext createApplicationContext() 
    { 
     return new AnnotationConfigApplicationContext(ContextConfig.class) 
    } 

    @Configuration 
    public static class ContextConfig extends CamelConfiguration 
    { 
     @Override 
     protected void setupCamelContext(CamelContext camelContext) throws Exception 
     { 
      super.setupCamelContext(camelContext); 
      camelContext.addComponent("hazelcast", new StubComponent()); 
      // some other unnecessary stuff 
     } 

     @Override 
     public List<RouteBuilder> routes() 
     { 
      final List<RouteBuilder> list = new ArrayList<>(); 
      list.add(new OnExceptionRoute()); 
      return list; 
     } 
    } 

    @Override 
    public boolean isUseAdviceWith() 
    { 
     return true; 
    } 

    @Test 
    public void testIOException() 
    { 
     context.getRouteDefinition("someQueueID") 
       .adviceWith(context, new AdviceWithRouteBuilder() 
       { 
        @Override 
        public void configure() throws Exception 
        { 
         this.weaveByType(OnExceptionDefinition.class) 
          .selectIndex(1) 
          .replace() 
           .onException(IOException.class, FileNotFound.class) 
            .asyncDelayedRedelivery() 
            .redeliveryDelay(10) 
            .maximumRedeliveries(3) 
            .log("modified io exception noticed") 
            .to("mock:ioError") 
           .end(); 
          ... 
          mockEndpoints(); 
        } 
       }); 
     context.start(); 
     MockEndpoint ioErrorEndpoint = getMockEndpoint("mock:ioError"); 
     ... 
     ioErrorEndpoint.setExpectedMessageCount(1); 
     ... 

     Map<String, Object> headers = new HashMap<>(); 
     headers.put("TestValue", new Integer(1)); 
     template.sendBodyAndHeaders("hazelcast:seda:someQueue", new Object(), headers); 

     ... 
     ioErrorEndpoint.assertIsSatisfied(); 
     ... 
    } 
} 

यहाँ परीक्षण सिर्फ IOException की onException खंड की जगह पहले 10 एमएस करने के लिए 3 मिनट से पुनर्वितरण देरी को कम करने के लिए और एक कहते हैं अंत में नकली समापन बिंदु।

java.lang.IllegalArgumentException: The output must be added as top-level on the route. Try moving OnException[[class java.io.IOException, class java.io.FileNotFoundException] -> []] to the top of route. 

हालांकि, official documentation में उदाहरण, जहाँ तक मैं उन्हें सही ढंग से समझ में आया, बहुत समान हैं: हालांकि जब मैं इकाई परीक्षण चलाने का प्रयास मैं निम्नलिखित अपवाद मिल जाएगा। मैंने परिभाषित आईडी भविष्यवाणी और इसकी संबंधित विधि weaveById() या weaveByToString() विधि के माध्यम से अपवाद परिभाषा को देखने का भी प्रयास किया लेकिन बिना किसी अन्य परिणाम के। मैंने weaveByType(OnExceptionDefinition.class).selectIndex(1).remove(); के माध्यम से अपवाद परिभाषा को हटाने की कोशिश की और weaveAddFirst().onException(...).async...; के माध्यम से ऑनएक्सप्शन भाग जोड़ें लेकिन उसी परिणाम के साथ।

हालांकि, एक नकली त्रुटि समापन बिंदु जोड़ना, f.e. के माध्यम से संभव है। weaveByToString("Log[io exception noticed]").after().to("mock:ioError");

तो अपवाद ब्लॉक पर संशोधन करने के लिए कोई सुझाव या यूनिट परीक्षणों के लिए पुनर्वितरण डेले स्वागत से अधिक हैं।


@Edit: मैं भी मार्ग परिभाषा (from(...)) के रूप में अपवाद संदेश ने सुझाव दिया और यह भी ऊंट के exception samples में वरीय मामला था ऊपर onException घोषणाओं स्थानांतरित करने के लिए अब की कोशिश की। ऐसा करने पर, हालांकि, सभी परीक्षण (यहां तक ​​कि काम करने वाले) NullPointerException के रूप में context.getRouteDefinition("someQueueID").adviceWith(context, new AdviceWithRouteBuilder() {... }); पर विफल हो जाते हैं क्योंकि स्पष्ट रूप से मार्ग स्वयं और नहीं पाया जा सकता है। मुझे संदेह है कि यह एक इंटेलिजे मुद्दा है क्योंकि दोनों वर्ग एक ही परियोजना के भीतर हैं और इसलिए मार्ग का एक संशोधन परीक्षण वर्ग के लिए दृश्यमान होना चाहिए।

उपयोग में

कैमल संस्करण: 2.13.0, IntelliJ विचार 13.1.2


@ EDIT2: किसी कारण से context.getRouteDefinitions("someQueueID") रिटर्न अशक्त OnException तत्वों, from ब्लॉक के बाहर परिभाषित कर रहे हैं अगर जबकि सामान्य मार्ग context.getRouteDefinitions().get(0) के माध्यम से प्राप्त किया जा सकता है - हालांकि, अपवाद बताते हुए कि ऑनएक्सप्शन भाग को शीर्ष-स्तर तत्व के रूप में जोड़ा जाना आवश्यक है।

+1

एक अन्य विकल्प redeliveryDelay (और शायद विभिन्न अन्य सेटिंग्स) एक संपत्ति बनाने, और फिर एक उत्पादन गुण फ़ाइल है + एक परीक्षण गुण, फ़ाइल प्रत्येक में आपकी आवश्यकताओं के अनुरूप मूल्यों भिन्न साथ वातावरण। –

+0

@ स्टेवहैरिंगटन हालांकि इन क्षेत्रों में संपत्ति मूल्यों को इंजेक्शन देने के साथ आपका सुझाव काम करता है, यह सलाह के लिए मूल मुद्दे को हल नहीं करता है। मेरी राय में अपवाद ब्लॉक के साथ संयोजन के साथ। हालांकि, अगर आप उत्तर पोस्ट करने के इच्छुक हैं तो मैं आपके सुझाव को उत्तर के रूप में स्वीकार करना चाहता हूं। –

उत्तर

4

जावा डीएसएल का उपयोग करते समय, मार्ग की आईडी .routeId() विधि का उपयोग करके सेट की गई है, .id() जैसा कि आपने उपरोक्त कोड किया है। इससे आपकी adviceWith चिंताओं में मदद मिल सकती है।

पुनः प्रयास विलंब के हार्ड कोडिंग के बजाय, विलंब गुणों का उपयोग करके विलंब कॉन्फ़िगर करने के लिए एक बेहतर तरीका होगा। अपने CamelSpringTestSupport कक्षा पर विधि useOverridePropertiesWithPropertiesComponent() के आसपास दस्तावेज़ देखें।

संपादित

आप onException खंड बुनाई की जरूरत नहीं है, बस एक नया एक राज्य। यहां एक संपूर्ण उदाहरण है:

import org.apache.camel.builder.AdviceWithRouteBuilder; 
import org.apache.camel.builder.RouteBuilder; 
import org.apache.camel.test.junit4.CamelTestSupport; 

public class DummyTest extends CamelTestSupport{ 
    @Override 
    protected RouteBuilder createRouteBuilder() throws Exception { 
     return new RouteBuilder(){ 
      @Override 
      public void configure() throws Exception { 

       from("direct://start") 
        .routeId("myroute") 
        .onException(Exception.class) 
         .id("myException") 
         .continued(true) 
        .end() 
        .throwException(new Exception()) 
        .to("mock:end"); 
      } 
     }; 
    } 

    @org.junit.Test 
    public void doTest() throws Exception{ 
     context.getRouteDefinition("myroute").adviceWith(context, new AdviceWithRouteBuilder(){ 
      @Override 
      public void configure() throws Exception { 
       context.getRouteDefinition("myroute") 
        .onException(Exception.class).setBody(constant("adviceWith")).continued(true); 
      }}); 
     context.start(); 
     template.sendBody("direct://start", "original"); 
     String bodyAtEndOfExchange = getMockEndpoint("mock:end") 
       .getExchanges().get(0).getIn().getBody(String.class); 
     assertEquals("adviceWith", bodyAtEndOfExchange);   
     context.stop(); 
    } 

    @Override 
    public boolean isUseAdviceWith() { 
     return true; 
    } 
} 
+0

मैंने पहले से ही '.id (...)' और '.routeId (...) 'के बारे में समस्या का पता लगाया है, लेकिन इसके बाद से इसे इंगित करने के लिए धन्यवाद क्योंकि मैंने तब से पोस्ट अपडेट नहीं किया था। मैंने @SteveHarrington द्वारा पहले से सुझाए गए गुणों के माध्यम से देरी को भी कॉन्फ़िगर किया है। हालांकि इसने परीक्षण-विशिष्ट विलय के मुद्दे को ठीक किया, फिर भी वास्तविक विषय अभी भी बना हुआ है - अपवाद ब्लॉक पर उचित तरीके से सलाह कैसे लें? बेशक, 'केवल' और 'to' को इंटरसेप्टरों का उपयोग करके पकड़ा जा सकता है, लेकिन अगर हम सड़क के बीच में कुछ जोड़ना चाहते हैं और आईडी का उपयोग नहीं करना चाहते हैं। सुनिश्चित नहीं है कि ऊंट 2.15+ अब बेहतर समर्थन के साथ आता है, इसे फिर से प्रयास करना होगा –

संबंधित मुद्दे