CamelContext.removeRouteDefinitions() does not remove direct:// endpoints - apache-camel

When I remove a route with CamelContext.removeRouteDefinitions(), I cannot add this route again beacause it says Endpoint direct://something only allows 1 active consumer but you attempted to start a 2nd consumer.
Is it normal? How can I remove those endpoints from the context?

You would need to remove the endpoint as well, there is API on CamelContext to remove endpoints.

Related

How to add an trailing slash to the camel http component of camel

Im am trying to call a rest post service from my Camel route.
The rest service is deployed at https://csp-verteileauftrag-camunda-v1-csp-ims-dev-az.apcn.osp4-preprod.hel.kko.ch/api/v1/verteileauftrag/.
Calling the Service from a Rest Client like VS Code works if there is a trailing slash (after verteileauftrag).
In my camel route I have configured the following:
restConfiguration().host("https://csp-verteileauftrag-camunda-v1-csp-ims-dev-az.apcn.osp4-preprod.hel.kko.ch/api/v1").component("http").bindingMode(RestBindingMode.json);
and in then later using the config:
.to("rest:post:verteileauftrag?outType=ch.helsana.csp.verteileauftrag.rest.model.apiadapter.ResponseType")
If I execute the code, I get a 404 HTTP Error from the Backend as the URL used is
https://csp-verteileauftrag-camunda-v1-csp-ims-dev-az.apcn.osp4-preprod.hel.kko.ch/api/v1/verteileauftrag. So without a trailing slash.
I have tried to add it like .to("rest:post:verteileauftrag/?outType=ch.helsana.csp.verteileauftrag.rest.model.apiadapter.ResponseType")
but no success.
Do you have any idea how to tell the http component in the rest configuration how to add the trailing slash?
Thank you very much.
Using redhat fuse 7_10_2.
Regards Michel
Based on a collegues example I reimplemented the Rest Service call with a normal .to("URL") configuration in the routebuilder with setting the appropriate Headers for HTTP Post and content type json. Would still be interessted in any answer, but not waiting on one.

camel - quartz2 endpoint - Multiple consumers for the same endpoint

I am using apache camel and wants to have multiple routes.The route is as below.
endpoint -> quartz2://tsTimer?cron=0%2F20+*+8-18+%3F+*+MON%2CTUE%2CWED%2CTHU%2CFRI+*&stateful=true&trigger.timeZone=Asia%2FSingapore
Call bean method to get data.
Send to MQ
In this case my route is going to be same as the polling interval is same.
The data from bean method will be different.
And the MQ queue will be same.
Failed to start route route2 because of Multiple consumers for the same endpoint is not allowed: quartz2://tsTimer?cron=0%2F20+*+8-18+%3F+*+MON%2CTUE%2CWED%2CTHU%2CFRI+*&stateful=true&trigger.timeZone=Asia%2FSingapore
How do i achieve this? How do i differentiate camel route in case when the endpoint is quartz2 timer?
I din't notice that in endpoint uri I was having tsTimer which will distinguishes other end-points.
Something like below
quartz2://tsTimer1
quartz2://tsTimer2
quartz2://tsTimer3

Apache camel Restlet producer cached

I am using camel 2.18.0 version.I am facing a issue while using restlet component in SEDA flow. Please find the route details below
from("timer://foo?repeatCount=1")
.to("http4://localhost:8080/pages")
.split(body())
.to("seda:pageConsumer");
from("seda:pageConsumer?concurrentConsumer=5")
.toD("restlet:${in.body}")
.process(enrich());
Details on route:
"http4://localhost:8080/pages" this rest endpoint returns list of url
url= http://localhost:8080/data?page=1&size=5
seda consumer is used for consuming each page parallel
url "http://localhost:8080/data?page=1&size=5" streams the data (This is a rest endpoint and endpont does not send a list of data instead endpoint streams the data)
restlet endpoint invokes the page url and streams the data.
Issue:
when seda endpoint receives 1st URL all is good i.e. "http://localhost:8080/data?page=1&size=5" rest endpoint is invoked by restlet and expected data is processed in route.
when seda endpoint receives 2nd URL i.e.
"http://localhost:8080/data?page=2&size=5" , this where issue starts instead of invoking rest endpoint with "page=2&size=5" as query param, restlet use query param from 1st URL i.e. "page=1&size=5". and issue continues for rest of the urls.
upon debugging i found out that camel caches producer in ProducerCache
and producer is cached in a hashmap with endpoint uri as the key.
questions why does camel does not honour query param during caching? is there why to avoid the caching?
Please note i got the code working by changing the url to include page details which is ugly. Currently url looks like
http://localhost:8080/data/page/2/size/5.
If the restlet endpoint is calling the same http url (eg host:port) then it can be slightly better to use a plain to with this host:port as static, and then set a header with the dynamic part.
.setHeader(Exchange.HTTP_QUERY, constant("page1=&size=5"))
.to("http:xxxx")
Then the same endpoint/producer is reused and the header then includes the dynamic part with the query parameters.
There is also a header where you can set the context-path as well on Exchange.
If you keep using toD then you can adjust the size of the cache with the cacheSize option - its the same as on recipient list: http://camel.apache.org/recipient-list.html

In IdentityServer4 how does the Google middleware handle the /signin-google callback after successful authentication?

I am using IdentityServer4. I have configured Google authentication middleware as seen here. However, the redirect uri registered with Google is <domain>/signin-google. Additionally, I know that the ExternalLoginCallback endpoint gets called after I have authenticated with Google and after the redirect uri that is registered with Google has been called (/signin-google).
My question is what happens between /signin-google and the call to /ExternalLoginCallback? What method(s) in the Google middleware are triggered once the browser is redirected to /signin-google but before the application/middleware eventually makes it to /ExternalLoginCallback?
If you look at the ASP.NET Core Security Github repo you can find the implementation of the Google middleware. Essentially, if you trace through the code you will see the GoogleHandler inherits from OAuthHandler<T> which inherits from RemoteAuthenticationHandler<T>. In RemoteAuthenticationHandler<T> you will see a method called ShouldHandleRequestAsync (here). This method checks the current URL versus the URL that is on the CallbackPath property on the Options object. This is how the authentication middleware is triggered after the redirect back from the authentication provider - it's handled by the middleware - NOT a controller. Once the middleware is triggered it resumes the authentication process.
All external authentication provider middleware works this way. Once the middleware is triggered a method called called HandleRemoteAuthentication in OAuthHandler is triggered. See here. This triggers the second leg of the OAuth 2.0 authorization code flow process where the one time use code obtained in the first leg of the process is exchanged for an access token. That process happens before the ExternalLoginCallback is triggered. Specifically, once the code has been exchanged for an access token and some user information is obtained from Google a ClaimsPrincipal is created and a temporary cookie is issued. By default the cookie is named idsrv.external. Then, as you can see in the IdentityServer4 Quickstart projects, the ExternalLoginCallback endpoint is triggered, the idsrv.external cookie is deleted and a new authentication cookie is issued for the ClaimsPrincipal.
The Google middleware overrides functionality from the base classes that is specific to Google, but essentially all of the OAuth 2.0/OpenID Connect middleware works this way.

Obtaining a previous message within an Apache Camel route

I'm pretty new to camel so perhaps I'm going about this the wrong way but I'm routing messages from one endpoint to another and transforming them on the way. However the next stage is to add authentication to the pipeline. I have a service that tracks authenticated users. My plan is to, in the first stage of the route, to add a filter that checks to see if the current user is authenticated. If the user is not I want to transform the message into an authentication request and send that to my endpoint. All good so far, however, after authentication (if successful) I want to send the original message down the pipeline. Is this something that can be done?
A simplified version of my route would be:
from("seda:in").
filter(method(Authentication.class, "isNotAuthenticated")).
bean(AuthenticationTransformer.class)
to("cxfbean:out")
.end()
.bean(RequestTransformer.class)
.to("cxfbean:out")
The same message would be sent to both transformer beans.
You should preserve the message in the Exchange property setProperty("originalMessage", body()) before transforming it. Afterwards you can access that property using getProperty("originalMessage")

Resources