Camel
  1. Camel
  2. CAMEL-4503

Recipient List cannot vary destination by changing property in an expression

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.8.1
    • Fix Version/s: 2.8.3, 2.9.0
    • Component/s: None
    • Labels:
      None
    • Estimated Complexity:
      Unknown

      Description

      This is probably due to producers being cached based on unresolved endpoint URI, rather than the resolved endpoint URI. Haven't tested this theory out though.

      See message on user list http://markmail.org/message/sdysp6sspq5lomf4

        Issue Links

          Activity

          Show
          Jonathan Anstey added a comment - IRC chat on this here http://irclogs.dankulp.com/logs/irclogger_log/karaf?date=2011-09-29,Thu&sel=335#l331
          Hide
          Achim Nierbeck added a comment - - edited

          Unfortunately I just realized that the mentioned workaround doesn't work

          I'm investigating why it isn't I'm down to the following right now:

          answer = endpoints.get(getEndpointKey(uri));

          in DefaultCamelContext does give me the wrong Endpoint, at least it's bound to the wrong URI.

          it's called from

          endpoint = resolveEndpoint(exchange, recipient);

          in RecipientListProcessor.createProcessorExchangePairs(...)

          The following scenario doesn't work right now for the workaround, this might be a different bug though:

          • Recipient A is resolved the way it should work and can be called
          • if Recipient B is questioned it also works and can be used.
          • if Recipient A is questioned from the cache again, Recipient B is provided and therefore the requests end up
            on the wrong host.

          I also added a comment to the mailing-list about this.

          Show
          Achim Nierbeck added a comment - - edited Unfortunately I just realized that the mentioned workaround doesn't work I'm investigating why it isn't I'm down to the following right now: answer = endpoints.get(getEndpointKey(uri)); in DefaultCamelContext does give me the wrong Endpoint, at least it's bound to the wrong URI. it's called from endpoint = resolveEndpoint(exchange, recipient); in RecipientListProcessor.createProcessorExchangePairs(...) The following scenario doesn't work right now for the workaround, this might be a different bug though: Recipient A is resolved the way it should work and can be called if Recipient B is questioned it also works and can be used. if Recipient A is questioned from the cache again, Recipient B is provided and therefore the requests end up on the wrong host. I also added a comment to the mailing-list about this.
          Hide
          Claus Ibsen added a comment -

          Okay the bug seems to be in camel-cxf, in CxfComponent.createEndpoint. As it return the same endpoint instance even though the ?address is different.

          Show
          Claus Ibsen added a comment - Okay the bug seems to be in camel-cxf, in CxfComponent.createEndpoint. As it return the same endpoint instance even though the ?address is different.
          Hide
          Claus Ibsen added a comment -

          CAMEL-4139 causes this problem, it will lookup existing bean by its id, and reuse that as CxfEndpoint.
          Even if CxfComponent is creating a new CxfEndpoint.

          It seems the problem is that if you omit the address in the <cxf:cxfEndpoint> in the XML file.
          And then you want to use that <cxf:cxfEndpoint> bean but specific the address at runtime. Then CxfComponent
          will still hand out a shared CxfEndpoint.

          It guess the tricky part is that with cxf:bean:xxx you refer to a bean, and then you also provide additional configurations which should override.
          This seems a hard path to support. Maybe cxf:bean:xxx should be made to not accept any parameters at all, if that makes sense.

          Alternative the cxf:bean:xxx should be sort of a template, and then being able to create "clones" of itself.

          Show
          Claus Ibsen added a comment - CAMEL-4139 causes this problem, it will lookup existing bean by its id, and reuse that as CxfEndpoint. Even if CxfComponent is creating a new CxfEndpoint. It seems the problem is that if you omit the address in the <cxf:cxfEndpoint> in the XML file. And then you want to use that <cxf:cxfEndpoint> bean but specific the address at runtime. Then CxfComponent will still hand out a shared CxfEndpoint. It guess the tricky part is that with cxf:bean:xxx you refer to a bean, and then you also provide additional configurations which should override. This seems a hard path to support. Maybe cxf:bean:xxx should be made to not accept any parameters at all, if that makes sense. Alternative the cxf:bean:xxx should be sort of a template, and then being able to create "clones" of itself.
          Hide
          Willem Jiang added a comment -

          In most case the configure of cxfEndpoint bean will not be changed, it should be OK if you just reuse the bean endpoint.
          If there are some parameter which can be used to override the configuration in the endpoint uri, we could clone a new endpoint to use.

          Show
          Willem Jiang added a comment - In most case the configure of cxfEndpoint bean will not be changed, it should be OK if you just reuse the bean endpoint. If there are some parameter which can be used to override the configuration in the endpoint uri, we could clone a new endpoint to use.
          Hide
          Claus Ibsen added a comment -

          Willem I have committed an unit tests that reproduces the issue
          tests/camel-itest/src/test/java/org/apache/camel/itest/greeter/RecipientListCxf2Test.java

          With your recent fix on trunk (eg the clone) the problem with picking up the wrong bean is resolved as far.
          But we get a NPE exception later.

          Caused by: java.lang.NullPointerException
          	at org.apache.camel.component.cxf.CxfProducer.prepareRequest(CxfProducer.java:168)
          	at org.apache.camel.component.cxf.CxfProducer.process(CxfProducer.java:89)
          	at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)
          	at org.apache.camel.processor.RedeliveryErrorHandler.processErrorHandler(RedeliveryErrorHandler.java:321)
          	at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:212)
          	at org.apache.camel.processor.UnitOfWorkProcessor.process(UnitOfWorkProcessor.java:102)
          	at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)
          	at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:575)
          

          The CxfBinding is null on the endpoint. So I guess a little more fix is needed. Do you mind digging into this?

          Show
          Claus Ibsen added a comment - Willem I have committed an unit tests that reproduces the issue tests/camel-itest/src/test/java/org/apache/camel/itest/greeter/RecipientListCxf2Test.java With your recent fix on trunk (eg the clone) the problem with picking up the wrong bean is resolved as far. But we get a NPE exception later. Caused by: java.lang.NullPointerException at org.apache.camel.component.cxf.CxfProducer.prepareRequest(CxfProducer.java:168) at org.apache.camel.component.cxf.CxfProducer.process(CxfProducer.java:89) at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73) at org.apache.camel.processor.RedeliveryErrorHandler.processErrorHandler(RedeliveryErrorHandler.java:321) at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:212) at org.apache.camel.processor.UnitOfWorkProcessor.process(UnitOfWorkProcessor.java:102) at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73) at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:575) The CxfBinding is null on the endpoint. So I guess a little more fix is needed. Do you mind digging into this?
          Hide
          Willem Jiang added a comment -

          @Claus
          That's my bad, I will update the copy method of CxfEndpoint by setting the list reference with a deep copy one.

          Show
          Willem Jiang added a comment - @Claus That's my bad, I will update the copy method of CxfEndpoint by setting the list reference with a deep copy one.
          Hide
          Willem Jiang added a comment -

          The NPE is caused by the clone method of CxfEndpoint, as you know CxfEndpoint extends the ServiceSupport object which has lots of AutomBoolean objects.
          If the CxfEndpoint instance is started, the cloned CxfEndpoint will not start again.
          It looks like calling the clone method is not a idea way to resolve such issue. I'm still looking for a good solution.

          Show
          Willem Jiang added a comment - The NPE is caused by the clone method of CxfEndpoint, as you know CxfEndpoint extends the ServiceSupport object which has lots of AutomBoolean objects. If the CxfEndpoint instance is started, the cloned CxfEndpoint will not start again. It looks like calling the clone method is not a idea way to resolve such issue. I'm still looking for a good solution.
          Hide
          Willem Jiang added a comment -

          This is fixed by CAMEL-4561

          Show
          Willem Jiang added a comment - This is fixed by CAMEL-4561

            People

            • Assignee:
              Willem Jiang
              Reporter:
              Jonathan Anstey
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development