On 19 October 2010 13:19, James Strachan <james.strac...@gmail.com> wrote: > On 19 October 2010 12:54, Willem Jiang <willem.ji...@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: ja...@fusesource.com Web: http://fusesource.com Twitter: jstrachan Blog: http://macstrac.blogspot.com/ Open Source Integration