camel-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From James Strachan <james.strac...@gmail.com>
Subject Re: implementing 'Protocols' or a way to make it easier to black box routes and compose them with other routes
Date Tue, 01 Mar 2011 09:08:58 GMT
On 19 October 2010 13:19, James Strachan <james.strachan@gmail.com> wrote:
> On 19 October 2010 12:54, Willem Jiang <willem.jiang@gmail.com> wrote:
>> On 10/19/10 6:06 PM, James Strachan wrote:
> [snip]
>>> Implementing Protocols
>>> =================
>>>
>>> So the realisation we came to was, we just need to combine a protocol
>>> bean RouteBuilder and a Component into a single, simple bean that we
>>> use Dependency Injection to create and configure. i.e. a single
>>> RouteBuilder can also be a Component as well which can then expose its
>>> public endpoints.
>>>
>>> e.g. here's a strawman...
>>>
>>> /**
>>>  * a simple protocol that does something but has a public
>>>  * input and output endpoint if you wish to communicate with the protocol
>>>  */
>>> public class MyProtocol extends ProtocolBuilder {
>>>   // variables injected..
>>>   private String input;
>>>   private String output;
>>>
>>>   protected void configure() {
>>>     // lets expose the public endpoints
>>>     alias("input", input);
>>>     alias("output", input);
>>>
>>>     // regular implementation detail routes go here...
>>>     from(input).
>>>       beanRef("foo", "bar").
>>>       to("foo:bar").
>>>       to(output);
>>>   }
>>>
>>>   // properties....
>>>  ...
>>> }
>>>
>>> Then folks could expose protocol A and B using Spring XML (these
>>> protocols don't have to be the same class BTW, just reusing it for
>>> brevity)...
>>>
>>> <bean id="a" class="MyProtocol">
>>>   <property name="input" value="activemq:Some.A.Input"/>
>>>   <property name="output" value="activemq:Some.A.Output"/>
>>> </bean>
>>>
>>> <bean id="b" class="MyProtocol">
>>>   <property name="input" value="mq:BlahBlah"/>
>>>   <property name="output" value="file:somethingOrOther"/>
>>> </bean>
>>>
>>>
>>> Then to route these two 'protocols' together we could refer to the
>>> public aliases (kinda like exported public methods in OO terms) via...
>>>
>>>    from("a://output").to("b://input")
>>
>> With this DSL, I don't think protocol-a's output is connect to the
>> protocol-b's input automatically.
>>
>> Maybe we should override their input or output definition by looking up the
>> position of these two protocols.
>
>
> So the idea is the ProtocolBuilder implements the
> Component.createEndpoint method
> http://camel.apache.org/maven/camel-2.2.0/camel-core/apidocs/org/apache/camel/Component.html#createEndpoint(java.lang.String)
>
> taking the "output" String and aliasing it to whatever real physical
> endpoint the ProtocolBuilder decides to map it to via the
> alias("output", something) method call. Its up to the ProtocolBuilder
> implementation to decide how to map a physical endpoint to a logical
> name.
>
> i.e. the alias() method in this strawman creates the map of logical
> names to physical endpoints used inside the routes; which can then be
> used to resolve endpoint URIs within the protocol instances namespace.
>
>
>>> (I kinda wanted to use the term "export" for these alias endpoints,
>>> but we use export in the DSL for exporting a service to an endpoint -
>>> the server side of "Spring Remoting" type stuff so didn't want to
>>> confuse folks with overusing the same term).
>>>
>>>
>>> So what does ProtocolBuilder do? Well its just a RouteBuilder
>>> extension which implements the "alias" methods. (Not 100% sure on the
>>> name "alias" yet).
>>>
>>>   public abstract ProtocolBuilder alias(String logicalName, String
>>> physicalEndpointUri);
>>>   public abstract ProtocolBuilder alias(String logicalName, Endpoint
>>> physicalEndpoint);
>>>
>>> Then it either needs to implement Component directly or have some kind
>>> of Type Converter to convert ProtocolBuilder to be a Component. The
>>> Component implementation just maps the logical endpoint name like
>>> "input" to whatever physical URI its using.
>>
>> Maybe a ProtocolComponent can do this job, and the DSL could be
>>
>> from(protocol://a).to(protocol://b);
>
> If there's only one input and output for protocols thats another
> option; though I can imagine many protocols having multiple inputs or
> outputs.
>
> e.g. there might be a dead letter error output (e.g. like stdin /
> stdout / stderr). Some protocols might have multiple inputs (e.g.
> doing a BAM protocol to correlate messages together).
>
> I guess having a protocol endpoint could just assume input and output
> as the default endpoint names. Or maybe we could name the logical
> endpoints within the protocols...
>
>  from("protocol://a/input").to("protocol://b/output")
>
> Though given how we need some API to look up in the RouteBuilder to
> find the logical -> physical mappings, I figured it was easiest to
> just add 1 new class which is-a RouteBuilder and is-a Component and so
> knows how to do the URI mapping from public name -> physical endpoint
> and can implement the alias() methods. It would also lead to simpler,
> shorter URIs...
>
>  from("a://input").to("b://output")
>
> Then folks can instantiate as many instances of a ProtocolBuilder as
> required - each instance getting its own scheme in Camel and so its
> own logical set of endpoint names which map to a separate set of
> physical endpoints.
>
> Camel already binds a URI scheme to a bean if it can convert itself to
> a Component; I figured protocols was a good use case of using that
> same behaviour, leading to short concise URIs.
>
> --
> James
> -------
> http://macstrac.blogspot.com/
>
> Open Source Integration
> http://fusesource.com/
>

Just to close this thread off; if anyone finds it searching: its
implemented here:
http://camel.apache.org/context.html

-- 
James
-------
FuseSource
Email: james@fusesource.com
Web: http://fusesource.com
Twitter: jstrachan
Blog: http://macstrac.blogspot.com/

Open Source Integration

Mime
View raw message