You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by Bruno Dusausoy <bd...@yp5.be> on 2010/10/28 10:23:54 UTC

Endpoint construction

Hi,

I have a small question about Endpoint construction.
I'm trying to construct an endpoint programmatically.
But I am missing something and I don't know what it is.

Take, for example, a simple case :

public class FileRouteBuilder extends RouteBuilder {

	public void configure() throws Exception {

		FileEndpoint input = new FileEndpoint();
		input.setCamelContext(getContext());
		input.setFile(new File("c:/post"));
		input.setDelete(true);

		FileEndpoint output = new FileEndpoint();
		output.setCamelContext(getContext());
		output.setFile(new File("c:/backup"));

		from(input).to(output);
	}
}

The endpoint URI for the input is shown, in the log, as :
[...]
INFO: Route: route1 started and consuming from: 
Endpoint[file://c:\post]
[...]

But, if I use string representation for the same endpoint - at least 
what I'm thinking is the same endpoint -, such as

public class FileRouteBuilder extends RouteBuilder {

	public void configure() throws Exception {

		from("file://c:/post?delete=true").to("file://c:/backup");
	}

}

I'm getting another URI :
[...]
INFO: Route: route1 started and consuming from: 
Endpoint[file://c:/post?delete=true]
[...]

So, it seems the options are missing.
Should I call a certain method in order to correctly build the 
Endpoint after setting the options ?

Regards.
--
Bruno Dusausoy
YP5 Software

--
Pensez environnement : limitez l'impression de ce mail.
Please don't print this e-mail unless you really need to.

Re: Endpoint construction

Posted by James Strachan <ja...@gmail.com>.
On 28 October 2010 10:25, Bruno Dusausoy <bd...@yp5.be> wrote:
> On Thu, 28 Oct 2010 11:04:49 +0200, Claus Ibsen <cl...@gmail.com>
> wrote:
> [...]
>>
>> You could most likely use setEndpointUriIfNotSpecified to set a pseudo
>> id, to differentiate the 2 of them
>>
> Indeed, it works.
>
> I've searched the reason why it worked like this and found that the
> toString() method in DefaultEndpoint is :
>
>    @Override
>    public String toString() {
>        return "Endpoint[" + getEndpointUri() + "]";
>    }
>
>    public String getEndpointUri() {
>        if (endpointUri == null) {
>            endpointUri = createEndpointUri();
>            if (endpointUri == null) {
>                throw new IllegalArgumentException("endpointUri is not
> specified and " + getClass().getName()
>                        + " does not implement createEndpointUri() to
> create a default value");
>            }
>        }
>        return endpointUri;
>    }
>
> And in FileEndpoint :
>
>    @Override
>    protected String createEndpointUri() {
>        return "file://" + getFile().getAbsolutePath();
>    }
>
> So indeed, it creates the same endpoint URI for both.

BTW there's also a constructor for most Endpoints which let you pass
in a URI of your choosing.

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

Open Source Integration

Re: Endpoint construction

Posted by Bruno Dusausoy <bd...@yp5.be>.
On Thu, 28 Oct 2010 11:04:49 +0200, Claus Ibsen <cl...@gmail.com>
wrote:
[...]
> 
> You could most likely use setEndpointUriIfNotSpecified to set a pseudo
> id, to differentiate the 2 of them
> 
Indeed, it works.

I've searched the reason why it worked like this and found that the
toString() method in DefaultEndpoint is :

    @Override
    public String toString() {
        return "Endpoint[" + getEndpointUri() + "]";
    }

    public String getEndpointUri() {
        if (endpointUri == null) {
            endpointUri = createEndpointUri();
            if (endpointUri == null) {
                throw new IllegalArgumentException("endpointUri is not
specified and " + getClass().getName()
                        + " does not implement createEndpointUri() to
create a default value");
            }
        }
        return endpointUri;
    }

And in FileEndpoint :

    @Override
    protected String createEndpointUri() {
        return "file://" + getFile().getAbsolutePath();
    }

So indeed, it creates the same endpoint URI for both.

Thanks.
-- 
Bruno Dusausoy
YP5 Software
--
Pensez environnement : limitez l'impression de ce mail.
Please don't print this e-mail unless you really need to.

Re: Endpoint construction

Posted by Claus Ibsen <cl...@gmail.com>.
On Thu, Oct 28, 2010 at 10:59 AM, Bruno Dusausoy <bd...@yp5.be> wrote:
> On Thu, 28 Oct 2010 09:34:54 +0100, James Strachan
> <ja...@gmail.com> wrote:
>
> [...]
>>
>> The only real difference is the 2nd version you specify the URI; the
>> first case the URI is auto-generated. Typically the auto-generated
>> URIs don't necessarily know which properties to add to the URI as
>> query arguments (as many properties have smart defaults etc).
>>
>> You can always set the URI you want it to look like in log statements
>> if you want; but typically its the same Endpoint object being used
>> under the covers; so its more a logging issue rather than a
>> functionality issue.
>>
>> e.g. you could replace...
>>
>>   FileEndpoint input = new FileEndpoint();
>>
>> with
>>
>>   FileEndpoint input = new FileEndpoint("file://c:/post?delete=true",
>> new FileComponent());
>>
>> to get the same logging output
>
> Well, I'm sorry but I tend to disagree about the problem being only a
> logging issue.
>
> Indeed, consider another simple example :
>
> public class FileRouteBuilder extends RouteBuilder {
>
>        public void configure() throws Exception {
>                from("file://c:/post?noop=true").to("file://c:/backup");
>                from("file://c:/post?readLock=none&delete=true").to("file://c:/backup2");
>        }
> }
>
> It works fine (even if there are better ways to express this, but
> that's out of scope) :
>
> [...]
> INFO: Route: route1 started and consuming from:
> Endpoint[file://c:/post?noop=true]
> 28 oct. 2010 10:59:02 org.apache.camel.impl.DefaultCamelContext start
> INFO: Route: route2 started and consuming from:
> Endpoint[file://c:/post?delete=true&readLock=none]
> 28 oct. 2010 10:59:02 org.apache.camel.impl.DefaultCamelContext start
> INFO: Started 2 routes
> [...]
>
> But, when expressing the same programmatically :
>
> public class FileRouteBuilder extends RouteBuilder {
>
>        public void configure() throws Exception {
>
>                FileEndpoint input = new FileEndpoint();
>                input.setCamelContext(getContext());
>                input.setFile(new File("c:/post"));
>                input.setNoop(true);
>
>                FileEndpoint input2 = new FileEndpoint();
>                input2.setCamelContext(getContext());
>                input2.setFile(new File("c:/post"));
>                input2.setReadLock("none");
>                input2.setDelete(true);
>
>                FileEndpoint output = new FileEndpoint();
>                output.setCamelContext(getContext());
>                output.setFile(new File("c:/backup"));
>
>                FileEndpoint output2 = new FileEndpoint();
>                output2.setCamelContext(getContext());
>                output2.setFile(new File("c:/backup2"));
>
>                from(input).to(output);
>                from(input2).to(output2);
>        }
> }
>
> I get this exception :
>
> Exception in thread "main"
> org.apache.camel.FailedToStartRouteException: Failed to start route
> route2 because of Multiple consumers for the same endpoint is not
> allowed: Endpoint[file://c:\post]
>
> So it seems options are really not taken into account, hence my
> original question.
>

You could most likely use setEndpointUriIfNotSpecified to set a pseudo
id, to differentiate the 2 of them


> Regards.
> --
> Bruno Dusausoy
> YP5 Software
> --
> Pensez environnement : limitez l'impression de ce mail.
> Please don't print this e-mail unless you really need to.
>



-- 
Claus Ibsen
-----------------
FuseSource
Email: cibsen@fusesource.com
Web: http://fusesource.com
Twitter: davsclaus
Blog: http://davsclaus.blogspot.com/
Author of Camel in Action: http://www.manning.com/ibsen/

Re: Endpoint construction

Posted by Bruno Dusausoy <bd...@yp5.be>.
On Thu, 28 Oct 2010 10:40:48 +0100, Hadrian Zbarcea
<hz...@gmail.com> wrote:
> Hi Bruno,
> 
> Your original question was: "Should I call a certain method in order
> to correctly build the Endpoint after setting the options ?". The
> answer to that is now.
> 
> On your disagreement, what James meant (I think) is that we could for
> instance do a better job at resetting an endpoint url, but that's not
> an easy task. We could for instance add all the parameters that change
> the default. Then you still have the problem of an uri for an endpoint
> that define a param with the same value as the default, so we'd have
> to strip those. We'd have to know what the default is, but we could
> use annotations for this. Or you could just add all the params on the
> logged uri, but then they can get fairly long.
> 
> This is an inconsistency, but it wasn't reported as a major issue
> until now. You seem to think that this is a major issue, correct?
> 

Not at all. This isn't a major issue for me.
In fact, it's not at all related to the issue I had.

Actually my problem was two separate problems mixing up.
I trusted the logging output which told me I had the same endpoint
("file://c:/post") twice, which wasn't really the case - but I didn't
know it at that time.
They were separate endpoints but since I didn't give any of them an
URI, Camel created an automatically generated one for each of them,
which, unfortunately resulted in the same URI, which was outputted by
the logging system.
What I thought, since the log output didn't show me the options part of
the URI, was that it was a "initialization" problem, like a method I
should have called in order to build the endpoint after having set the
options.

So Claus pointed me to the setEndpointUriIfNotSpecified() method, which
solved the problem.

I'm not sure if I clearly explained my issue.

Regards.
-- 
Bruno Dusausoy
YP5 Software
--
Pensez environnement : limitez l'impression de ce mail.
Please don't print this e-mail unless you really need to.

Re: Endpoint construction

Posted by Hadrian Zbarcea <hz...@gmail.com>.
Hi Bruno,

Your original question was: "Should I call a certain method in order to correctly build the Endpoint after setting the options ?". The answer to that is now.

On your disagreement, what James meant (I think) is that we could for instance do a better job at resetting an endpoint url, but that's not an easy task. We could for instance add all the parameters that change the default. Then you still have the problem of an uri for an endpoint that define a param with the same value as the default, so we'd have to strip those. We'd have to know what the default is, but we could use annotations for this. Or you could just add all the params on the logged uri, but then they can get fairly long.

This is an inconsistency, but it wasn't reported as a major issue until now. You seem to think that this is a major issue, correct?

Hadrian


On Oct 28, 2010, at 9:59 AM, Bruno Dusausoy wrote:

> On Thu, 28 Oct 2010 09:34:54 +0100, James Strachan
> <ja...@gmail.com> wrote:
> 
> [...]
>> 
>> The only real difference is the 2nd version you specify the URI; the
>> first case the URI is auto-generated. Typically the auto-generated
>> URIs don't necessarily know which properties to add to the URI as
>> query arguments (as many properties have smart defaults etc).
>> 
>> You can always set the URI you want it to look like in log statements
>> if you want; but typically its the same Endpoint object being used
>> under the covers; so its more a logging issue rather than a
>> functionality issue.
>> 
>> e.g. you could replace...
>> 
>>  FileEndpoint input = new FileEndpoint();
>> 
>> with
>> 
>>  FileEndpoint input = new FileEndpoint("file://c:/post?delete=true",
>> new FileComponent());
>> 
>> to get the same logging output
> 
> Well, I'm sorry but I tend to disagree about the problem being only a
> logging issue.
> 
> Indeed, consider another simple example :
> 
> public class FileRouteBuilder extends RouteBuilder {
> 
> 	public void configure() throws Exception {	
> 		from("file://c:/post?noop=true").to("file://c:/backup");
> 		from("file://c:/post?readLock=none&delete=true").to("file://c:/backup2");
> 	}
> }
> 
> It works fine (even if there are better ways to express this, but
> that's out of scope) :
> 
> [...]
> INFO: Route: route1 started and consuming from:
> Endpoint[file://c:/post?noop=true]
> 28 oct. 2010 10:59:02 org.apache.camel.impl.DefaultCamelContext start
> INFO: Route: route2 started and consuming from:
> Endpoint[file://c:/post?delete=true&readLock=none]
> 28 oct. 2010 10:59:02 org.apache.camel.impl.DefaultCamelContext start
> INFO: Started 2 routes
> [...]
> 
> But, when expressing the same programmatically :
> 
> public class FileRouteBuilder extends RouteBuilder {
> 
> 	public void configure() throws Exception {	
> 
> 		FileEndpoint input = new FileEndpoint();
> 		input.setCamelContext(getContext());
> 		input.setFile(new File("c:/post"));
> 		input.setNoop(true);
> 		
> 		FileEndpoint input2 = new FileEndpoint();
> 		input2.setCamelContext(getContext());
> 		input2.setFile(new File("c:/post"));
> 		input2.setReadLock("none");
> 		input2.setDelete(true);
> 		
> 		FileEndpoint output = new FileEndpoint();
> 		output.setCamelContext(getContext());
> 		output.setFile(new File("c:/backup"));
> 
> 		FileEndpoint output2 = new FileEndpoint();
> 		output2.setCamelContext(getContext());
> 		output2.setFile(new File("c:/backup2"));
> 						
> 		from(input).to(output);
> 		from(input2).to(output2);		
> 	}
> }
> 
> I get this exception :
> 
> Exception in thread "main"
> org.apache.camel.FailedToStartRouteException: Failed to start route
> route2 because of Multiple consumers for the same endpoint is not
> allowed: Endpoint[file://c:\post]
> 
> So it seems options are really not taken into account, hence my
> original question.
> 
> Regards.
> -- 
> Bruno Dusausoy
> YP5 Software
> --
> Pensez environnement : limitez l'impression de ce mail.
> Please don't print this e-mail unless you really need to.


Re: Endpoint construction

Posted by Bruno Dusausoy <bd...@yp5.be>.
On Thu, 28 Oct 2010 09:34:54 +0100, James Strachan
<ja...@gmail.com> wrote:

[...]
> 
> The only real difference is the 2nd version you specify the URI; the
> first case the URI is auto-generated. Typically the auto-generated
> URIs don't necessarily know which properties to add to the URI as
> query arguments (as many properties have smart defaults etc).
> 
> You can always set the URI you want it to look like in log statements
> if you want; but typically its the same Endpoint object being used
> under the covers; so its more a logging issue rather than a
> functionality issue.
> 
> e.g. you could replace...
> 
>   FileEndpoint input = new FileEndpoint();
> 
> with
> 
>   FileEndpoint input = new FileEndpoint("file://c:/post?delete=true",
> new FileComponent());
> 
> to get the same logging output

Well, I'm sorry but I tend to disagree about the problem being only a
logging issue.

Indeed, consider another simple example :

public class FileRouteBuilder extends RouteBuilder {

	public void configure() throws Exception {	
		from("file://c:/post?noop=true").to("file://c:/backup");
		from("file://c:/post?readLock=none&delete=true").to("file://c:/backup2");
	}
}

It works fine (even if there are better ways to express this, but
that's out of scope) :

[...]
INFO: Route: route1 started and consuming from:
Endpoint[file://c:/post?noop=true]
28 oct. 2010 10:59:02 org.apache.camel.impl.DefaultCamelContext start
INFO: Route: route2 started and consuming from:
Endpoint[file://c:/post?delete=true&readLock=none]
28 oct. 2010 10:59:02 org.apache.camel.impl.DefaultCamelContext start
INFO: Started 2 routes
[...]

But, when expressing the same programmatically :

public class FileRouteBuilder extends RouteBuilder {

	public void configure() throws Exception {	

		FileEndpoint input = new FileEndpoint();
		input.setCamelContext(getContext());
		input.setFile(new File("c:/post"));
		input.setNoop(true);
		
		FileEndpoint input2 = new FileEndpoint();
		input2.setCamelContext(getContext());
		input2.setFile(new File("c:/post"));
		input2.setReadLock("none");
		input2.setDelete(true);
		
		FileEndpoint output = new FileEndpoint();
		output.setCamelContext(getContext());
		output.setFile(new File("c:/backup"));

		FileEndpoint output2 = new FileEndpoint();
		output2.setCamelContext(getContext());
		output2.setFile(new File("c:/backup2"));
						
		from(input).to(output);
		from(input2).to(output2);		
	}
}

I get this exception :

Exception in thread "main"
org.apache.camel.FailedToStartRouteException: Failed to start route
route2 because of Multiple consumers for the same endpoint is not
allowed: Endpoint[file://c:\post]

So it seems options are really not taken into account, hence my
original question.

Regards.
-- 
Bruno Dusausoy
YP5 Software
--
Pensez environnement : limitez l'impression de ce mail.
Please don't print this e-mail unless you really need to.

Re: Endpoint construction

Posted by James Strachan <ja...@gmail.com>.
On 28 October 2010 09:23, Bruno Dusausoy <bd...@yp5.be> wrote:
> Hi,
>
> I have a small question about Endpoint construction.
> I'm trying to construct an endpoint programmatically.
> But I am missing something and I don't know what it is.
>
> Take, for example, a simple case :
>
> public class FileRouteBuilder extends RouteBuilder {
>
>        public void configure() throws Exception {
>
>                FileEndpoint input = new FileEndpoint();
>                input.setCamelContext(getContext());
>                input.setFile(new File("c:/post"));
>                input.setDelete(true);
>
>                FileEndpoint output = new FileEndpoint();
>                output.setCamelContext(getContext());
>                output.setFile(new File("c:/backup"));
>
>                from(input).to(output);
>        }
> }
>
> The endpoint URI for the input is shown, in the log, as :
> [...]
> INFO: Route: route1 started and consuming from: Endpoint[file://c:\post]
> [...]
>
> But, if I use string representation for the same endpoint - at least what
> I'm thinking is the same endpoint -, such as
>
> public class FileRouteBuilder extends RouteBuilder {
>
>        public void configure() throws Exception {
>
>                from("file://c:/post?delete=true").to("file://c:/backup");
>        }
>
> }
>
> I'm getting another URI :
> [...]
> INFO: Route: route1 started and consuming from:
> Endpoint[file://c:/post?delete=true]
> [...]
>
> So, it seems the options are missing.
> Should I call a certain method in order to correctly build the Endpoint
> after setting the options ?

The only real difference is the 2nd version you specify the URI; the
first case the URI is auto-generated. Typically the auto-generated
URIs don't necessarily know which properties to add to the URI as
query arguments (as many properties have smart defaults etc).

You can always set the URI you want it to look like in log statements
if you want; but typically its the same Endpoint object being used
under the covers; so its more a logging issue rather than a
functionality issue.

e.g. you could replace...

  FileEndpoint input = new FileEndpoint();

with

  FileEndpoint input = new FileEndpoint("file://c:/post?delete=true",
new FileComponent());

to get the same logging output

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

Open Source Integration