2011-11-04 28 views
6

Tôi đã có một mô hình lặp lại trên các tuyến đường của tôi - một bộ xử lý nhất định cần cùng 3 Headers thiết mỗi khi tôi gọi nó, vì vậy tôi đã có đoạn mã sau vào tuyến đường của tôi về 10+ lần:Lạc đà - mở rộng Java DSL?

.whatever() 
.setHeader("foo1", "bar1") 
.setHeader("foo2", "bar2") 
.setHeader("foo3", "bar3") 
.processRef("processorBazThatNeedsHeaders") 
.whatever() 

Các tiêu đề được phổ biến theo thời gian khác nhau, vì vậy việc trừu tượng hóa điều này thành một subroute không thực sự mua cho tôi bất cứ điều gì.

Những gì tôi yêu để có thể làm là lớp con RouteDefinition để có một phương pháp khác trong DSL của tôi mà sẽ cho phép tôi làm điều này:

.whatever() 
.bazProcessor("bar1", "bar2", "bar3") 
.whatever() 

và trong 'bazProcessor', thiết lập các tiêu đề và gọi bộ xử lý .

Tôi đã cố gắng thực hiện điều này nhưng có vẻ như chỉ có thể thực hiện được với một số phẫu thuật nghiêm trọng có thể không phải là tương lai, và có vẻ như là others have had similar luck.

Tôi cần chúng được đặt làm tiêu đề thay vì truyền chúng như tham số trực tiếp cho bộ xử lý vì các giá trị cũng được sử dụng sau khi bộ xử lý định tuyến.

Có một số cơ sở ẩn để đạt được điều gì đó như thế này không?

Trả lời

6

Bằng cách phân lớp RouteDefinition, tiện ích của bạn sẽ chỉ hiển thị trực tiếp sau from(...). Điều này có thể là một hạn chế nếu bạn muốn sử dụng phần mở rộng DSL, ví dụ sau DSL filter(...).

Cách tiếp cận đơn giản hơn là đóng gói logic ở đâu đó và sử dụng nó trong lớp thực hiện giao diện org.apache.camel.Processor và sau đó gọi quá tải .process(...) hoặc bean(...) trên tuyến đường để sử dụng logic. Bạn sẽ thực sự rất gần với một phần mở rộng DSL nếu bạn sử dụng tên có ý nghĩa cho cá thể Processor hoặc phương thức, trả về phiên bản Processor đó. Đây là một số example of the suggested approach. Cuối cùng, mã của bạn có thể trông giống như:

.whatever()
.process (setTheHeadersForBaz)
.whatever()

Chỉ cần để tham khảo: nếu bạn thực sự cần phải làm một DSL, có một dự án mở rộng Camel DSL based on Groovy. Tôi đoán một cách Scala dựa trên Camel Scala DSL cũng có thể là một lựa chọn.

+0

Đây là một ý tưởng tốt. Những gì tôi cần là * hơi * khác nhau nhưng tôi nghĩ rằng đây là một khởi đầu tốt. Tôi sẽ bắn và trả lời. –

+0

Bạn có thể nêu chi tiết câu trả lời của mình không? Tôi không hiểu nó: ( – Edmondo1984

1

Vì vậy, bạn chỉ đặt tiêu đề vì bạn muốn Bộ xử lý có quyền truy cập vào các giá trị đó?

Nếu vậy thì một ví dụ đơn giản sử dụng một nhà máy có thể trông như thế này:

whatever() 
    .process(BazProcessorFactory.instance("bar1", "bar2", "bar3")) 
    .whatever() 

Trường hợp BazProcessorFactory chỉ là một wrapper xung quanh xử lý của bạn:

public class BazProcessorFactory { 
    public Processor instance(final String...vals) { 
    return new Processor() { 
     @Override 
     public void process(Exchange exchange) throws Exception { 
     //access your array of values here 
     System.out.println("Foo1 = "+vals[0]); 
     } 
    } 
    } 
} 
+0

Cảm ơn Damo - Tôi thực sự cần chúng được đặt làm tiêu đề - chúng được bộ xử lý sử dụng nhưng chúng cũng được sử dụng sau khi bộ vi xử lý xử lý một số định tuyến. một lưu ý cho câu hỏi ban đầu –

1

Mặc dù hơi không thích hợp, đây là một ví dụ về việc mở rộng Scala DSL.

Chúng tôi có thể tạo một phương thức ngầm định cho đặc điểm DSL thông qua lớp ẩn.

object DSLImplicits { 
    implicit class RichDSL(val dsl: DSL) { 
    def get = dsl.setHeader(Exchange.HTTP_METHOD, _ => HttpMethods.GET.name) 

    def post = dsl.setHeader(Exchange.HTTP_METHOD, _ => HttpMethods.POST.name) 
    } 
} 

Và sử dụng nó như thế này.

import DSLImplicits.RichDSL 
//---------------------------- 
from("someWhere") 
    //Do some processing 
    .get.to("http://somewhere.com") 

Chi tiết @ http://siliconsenthil.in/blog/2013/07/11/apache-camel-with-scala-extending-dsl/

+0

@kleopatra: Cảm ơn .. đã hoàn thành. :) – siliconsenthil

Các vấn đề liên quan