[ 
https://issues.apache.org/jira/browse/CAMEL-19243?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17708425#comment-17708425
 ] 

Raymond edited comment on CAMEL-19243 at 4/4/23 1:36 PM:
---------------------------------------------------------

Yes, that's a good point, but I think this contradicts the whole concept of a 
Camel route. When used as a Camel component, I would expect that it behaves 
like one.

I could write the route like this:
{code:java}
<route id="example">
  <from uri="kamelet:timer-source?message=hello&amp;period=10000"/>
  <to uri="kamelet:log-sink"/>  
</route> {code}
But cannot write it like this
{code:java}
<route id="example">
  <from uri="kamelet:timer-source?message=hello&amp;period=10000"/>
  <to uri="log:fo"/>  
</route>{code}
I saw there is this remark in the docs

"To let the *Kamelet* component wiring the materialized route to the caller 
processor, we need to be able to identify the input and output endpoint of the 
route and this is done by using {{kamelet:source}} to mark the input endpoint 
and {{kamelet:sink}} for the output endpoint."

A couple of remarks:

1. I don't think it's a good idea that we need to check that remark to find out 
that the component contradicts with default behavior of components. Developers 
needs to rely on consistent behavior. It's like the cross on GUI windows people 
need to rely that the cross closes the window, not has other kinds of behavior.
2. I don't get the remark as well. At least it is better to say "The kamelet 
component cannot be used standalone, a route needs at least one kamelet:source 
and one kamelet:sink". Also the error could say something about "Missing a sink 
kamelet"
3. There is no reason why the concept of kamelets and the concept of routes 
should contradict each other, when developers can overwrite/remove the 
kamelet:source and kamelet:sink.

I think in general, that I don't have such a specific use case, but that 
Kamelets are extremely powerful to create integration especially combined with 
each other. It's a convention over configuration approach that saves a lot of 
time. In for example Kaoto this is also possible (combining camel components 
and kamelets), but it's better to solve this on a framework level than on a 
tooling/runtime level.

In Assimbly I for now solved it on the runtime level, and it works like a 
charm. I can combine regular components with kamelets. In the DIL (Data 
integration language) the configuration of a flow looks like this:
{code:java}
            <flow>
               <id>65</id>
               <name>Kamelet</name>
               <type>flow</type>
               <version>9</version>
               <dependencies>
                  <dependency>kamelet</dependency>
                  <dependency>file</dependency>
               </dependencies>
               <steps>
                  <step>
                     <id>68</id>
                     <type>error</type>
                     <uri>file://C:\messages\error</uri>
                  </step>
                  <step>
                     <id>65</id>
                     <type>source</type>
                     <uri>timer</uri>
                     <options>
                        <period>15000</period>
                        <message>Some message</message>            
                     </options>
                  </step>
                  <step>
                     <id>66</id>
                     <type>action</type>
                     <uri>log</uri>
                  </step>
                  <step>
                     <id>67</id>
                     <type>sink</type>
                     <uri>file://C:\messages\out</uri>
                  </step>
               </steps>
            </flow>{code}
You can find more in this blog:

[https://medium.com/p/ada578784efa]

There is also some remark on Kamelets as its a similar concept:

[https://medium.com/p/3411be21d931]


was (Author: skin27):
Yes, that's a good point, but I think this contradicts the whole concept of 
Camel route. When used as Camel component I would expect that it behaves like 
one.

I could write the route like this:


{code:java}
<route id="example">
  <from uri="kamelet:timer-source?message=hello&amp;period=10000"/>
  <to uri="kamelet:log-sink"/>  
</route> {code}

But cannot write it like this


{code:java}
<route id="example">
  <from uri="kamelet:timer-source?message=hello&amp;period=10000"/>
  <to uri="log:fo"/>  
</route>{code}

I saw there is this remark in the docs

"To let the *Kamelet* component wiring the materialized route to the caller 
processor, we need to be able to identify the input and output endpoint of the 
route and this is done by using {{kamelet:source}} to mark the input endpoint 
and {{kamelet:sink}} for the output endpoint."

A couple of remarks:

1. I don't think it's a good idea that we need to check that remark to find out 
that the component contradicts with default behavior of components. Developers 
needs to rely on consistent behavior. It's like the cross on 
2. I don't get the remark as well. At least better to say "The kamelet 
component cannot be used standalone at needs at least one kamelet:source and 
one kamelet:sink". Also the error could say something about "Missing sink 
kamelet"
3. There is no reason why the concept of kamelets and the concept of routes 
should contradicts each other. When one can overwrite/remove the kamelet:source 
and kamelet:sink.

I think in general, that I don't have such a specific use case, but that 
Kamelets are extremely powerful to create integration especially combined with 
each other. In for example Kaoto this is also possible, but better to solve 
this on a framework level than the tooling/runtime level.

In Assimbly I for now solved it on the runtime level, and it works like a 
charm. I can combine regular components with kamelets. In the DIL (Data 
integration language) this looks like this:
{code:java}

            <flow>
               <id>65</id>
               <name>Kamelet</name>
               <type>flow</type>
               <version>9</version>
               <dependencies>
                  <dependency>kamelet</dependency>
                  <dependency>file</dependency>
               </dependencies>
               <steps>
                  <step>
                     <id>68</id>
                     <type>error</type>
                     <uri>file://C:\messages\error</uri>
                  </step>
                  <step>
                     <id>65</id>
                     <type>source</type>
                     <uri>timer</uri>
                     <options>
                        <period>15000</period>
                        <message>Some message</message>            
                     </options>
                  </step>
                  <step>
                     <id>66</id>
                     <type>action</type>
                     <uri>log</uri>
                  </step>
                  <step>
                     <id>67</id>
                     <type>sink</type>
                     <uri>file://C:\messages\out</uri>
                  </step>
               </steps>
            </flow>{code}

You can find more in this blog:

[https://medium.com/p/ada578784efa]

There is also some remark on Kamelets as its a similar concept:

[https://medium.com/p/3411be21d931]

> KameletConsumerNotAvailableException
> ------------------------------------
>
>                 Key: CAMEL-19243
>                 URL: https://issues.apache.org/jira/browse/CAMEL-19243
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-kamelet
>    Affects Versions: 3.20.3
>            Reporter: Raymond
>            Priority: Minor
>
> I would like to use the Kamelets from the Kamelet catalog:
> [https://camel.apache.org/camel-kamelets/3.20.x/index.html]
> I have added the Kamelets maven dependency to my project 
> [https://mvnrepository.com/artifact/org.apache.camel.kamelets/camel-kamelets]
> And then use it within a route using the Kamelet component:
> {code:java}
> <route id="example">
>   <from uri="kamelet:timer-source?message=hello&amp;period=10000"/>
>   <to uri="log:foo"/>
> </route> {code}
>  
> This gives the following error:
> {code:java}
> 2023-04-03 15:50:03.073 ERROR 40304 --- [ - timer://tick] 
> o.a.c.p.e.DefaultErrorHandler            : Failed delivery for (MessageId: 
> 7E14905736F56C0-000000000000001C on ExchangeId: 
> 7E14905736F56C0-000000000000001C). Exhausted after delivery attempt: 1 
> caught: 
> org.apache.camel.component.kamelet.KameletConsumerNotAvailableException: No 
> consumers available on endpoint: kamelet://sink?routeId=timer-source-1. 
> Exchange[7E14905736F56C0-000000000000001C]Message History
> ---------------------------------------------------------------------------------------------------------------------------------------
> Source                                   ID                             
> Processor                                          Elapsed (ms)
> timer-source.kamelet.yaml:64             timer-source-1/timer-source-1  
> from[timer://tick?period=10000]                       481757935
> timer-source.kamelet.yaml:70             timer-source-1/setBody6        
> setBody[constant{{{message}}}]                                1
> timer-source.kamelet.yaml:72             timer-source-1/setHeader6      
> setHeader[Content-Type]                                       0
> timer-source.kamelet.yaml:75             timer-source-1/to15            
> kamelet://sink?routeId=timer-source-8                         0Stacktrace
> ---------------------------------------------------------------------------------------------------------------------------------------org.apache.camel.component.kamelet.KameletConsumerNotAvailableException:
>  No consumers available on endpoint: kamelet://sink?routeId=timer-source-1. 
> Exchange[7E14905736F56C0-000000000000001C]
>         at 
> org.apache.camel.component.kamelet.KameletProducer.process(KameletProducer.java:78)
>         at 
> org.apache.camel.processor.SendProcessor.process(SendProcessor.java:172)
>         at 
> org.apache.camel.processor.errorhandler.RedeliveryErrorHandler$SimpleTask.run(RedeliveryErrorHandler.java:477)
>         at 
> org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.schedule(DefaultReactiveExecutor.java:181)
>         at 
> org.apache.camel.impl.engine.DefaultReactiveExecutor.scheduleMain(DefaultReactiveExecutor.java:59)
>         at org.apache.camel.processor.Pipeline.process(Pipeline.java:165)
>         at 
> org.apache.camel.impl.engine.CamelInternalProcessor.process(CamelInternalProcessor.java:392)
>         at 
> org.apache.camel.component.timer.TimerConsumer.sendTimerExchange(TimerConsumer.java:210)
>         at 
> org.apache.camel.component.timer.TimerConsumer$1.run(TimerConsumer.java:76)
>         at java.base/java.util.TimerThread.mainLoop(Timer.java:556)
>         at java.base/java.util.TimerThread.run(Timer.java:506)2023-04-03 
> 15:50:03.074  WARN 40304 --- [ - timer://tick] 
> o.a.camel.component.timer.TimerConsumer  : Error processing exchange. 
> Exchange[7E14905736F56C0-000000000000001C]. Caused by: 
> [org.apache.camel.component.kamelet.KameletConsumerNotAvailableException - No 
> consumers available on endpoint: kamelet://sink?routeId=timer-source-1. 
> Exchange[7E14905736F56C0-000000000000001C]]
> {code}
> Looking at the source of the timer-source Kamelet this is logical:
> [https://github.com/apache/camel-kamelets/blob/main/kamelets/timer-source.kamelet.yaml]
> It has a line:
> to: kamelet:sink
> I'm not sure what this "kamelet:sink" does (all kamels from the catalog have 
> it)? When I remove it or change it with another uri (like direct:x) and load 
> the yaml from a custom location then the kamelet works.
> Is this a bug? Is this as intended?
> In other words, how can I use the kamelets from the catalog within my routes? 
> And is there a way to remove or overwrite the kamelet:sink?



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to