Thanks for the feedback Stephan - you explained a behavior I was seeing when I was putting this together (item 2 in the list below).
I tried doing this with the Blueprint DSL to see what happens, and the route behaves as I’d expect. When I stop the bundle providing the service, I get a ServiceUnavailableException (after the timeout). When I start the bundle providing the service back up, the route will continue to process normally - with a new instance of the service. The only odd part here is the output of the Karaf “list” command - it shows the bundle is in a “Waiting” state (https://issues.apache.org/jira/browse/KARAF-4283 <https://issues.apache.org/jira/browse/KARAF-4283>). So as near as I can tell, this is a bug. The Blueprint proxies are not being used somehow when they are injected into the RouteBuilder (and ultimately the route). Unless someone has some other idea, I’ll get a sample put together on GitHub and open a JIRA issue for this. Here’s the Blueprint that works: <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd" > <bean id="shutdown" class="org.apache.camel.impl.DefaultShutdownStrategy"> <property name="timeout" value="30"/> </bean> <reference id="echo-service" interface="com.pronoia.test.osgi.service.Echo" filter="instance=one" timeout="2000" /> <camelContext id="blueprint-context" xmlns="http://camel.apache.org/schema/blueprint"> <route id="blueprint-route"> <from uri="timer://blueprint-route?period=5000"/> <setBody> <exchangeProperty>CamelTimerFiredTime</exchangeProperty> </setBody> <log message="Calling Service via Reference: ${body}" /> <bean ref="echo-service" /> <log message="Finished"/> <to uri="mock://result"/> </route> </camelContext> </blueprint> > On Jan 26, 2016, at 11:52 PM, Siano, Stephan <stephan.si...@sap.com> wrote: > > Hi, > > Sorry for the confusion I may have caused. In your example you are using > option 3, which should actually work as you expected. > > Best regards > Stephan > > -----Original Message----- > From: Siano, Stephan [mailto:stephan.si...@sap.com] > Sent: Mittwoch, 27. Januar 2016 07:40 > To: users@camel.apache.org > Subject: RE: Invoking Dynamic OSGi Blueprint services from a Java RouteBuilder > > Hi, > > You have actually two issues. The first Is accessing an OSGi service from a > route using Java DSL. Camel lookups are done in a Camel registry. The kind of > registry depends on the way you start your camel context, if you are using > blueprint to do that, you have a blueprint registry, if you are using Spring > you have a spring registry and (AFAIK) if you are using Java DSL you are > normally using a JNDI registry. The special thing about the blueprint > registry is that it forwards lookups that cannot be resolved from the > blueprint context to the OSGi service registry (so you can do lookups with > the Camel registry that are doing OSGi service lookups). I don't think that > is possible with Java DSL. However these OSGi lookups via the Camel registry > are not very dynamic: The service object is retrieved via OSGi API and is > pinned in memory (which is not exactly OSGi-like). > > The other issue is when you are referencing services with blueprint. The user > of this blueprint service reference will not get the service object itself, > but a dynamic proxy object, that will remain the same even if you restart the > service (it will even delay any calls to the service while it is gone to the > time till it is back (or times out)). That way references injected during > bundle startup will remain valid even if the underlying service is restarted. > > Therefore you can encounter three different behaviours when referencing an > OSGi service (however this is registered) in a Camel route: > 1. trying to reference it via the camel registry with a registry > implementation different from the blueprint one doesn't work > 2. referencing it via the camel registry with the blueprint implementation > will work but only unless you restart the service > 3. referencing the service via blueprint service reference and then > referencing the service from the camel route will create a dynamic proxy > object (that remains the same over the whole lifecycle but can cope with > service restarts just all right). > > Best regards > Stephan > > -----Original Message----- > From: Quinn Stevenson [mailto:qu...@pronoia-solutions.com] > Sent: Dienstag, 26. Januar 2016 23:11 > To: users@camel.apache.org > Subject: Invoking Dynamic OSGi Blueprint services from a Java RouteBuilder > > When I use an OSGi Service registered using Blueprint from a Java route > (built using a Java RouteBuilder), the Camel route isn’t detecting the when > the service is not available, and it isn’t updating when the service > implementation changes. > > The simple setup I’m using has a Java interface for the OSGi service in one > bundle, and implementation of that interface which uses Blueprint to register > the service in another bundle, and simple RouteBuilder that uses the service > in a third bundle. The implementation of the service is injected into the > RouteBuilder using Blueprint, and the Camel context is configured in > Blueprint in a fourth bundle. > > After all these bundles are installed and started in Karaf, the run and the > hashCode of service is logged every time the Camel timer fires and triggers > an exchange. If I stop the bundle that registers the service using > Blueprint, the route continues to log the same hashCode when it calls the > OSGi service. I would expect a ServiceUnavailableException after a timeout. > > Additionally, when I restart the bundle that registers the service object, I > continue to get the same hashCode. I would expect to get a new hashCode > value. > > Am I doing something wrong? Do I need to do something different do get the > dynamic behavior I’m looking for? > > > The code looks like this: > > Java Interface (service-interface bundle): > public interface Echo { > String execute(String body); > } > > Java Implementation: > public class EchoServiceOne implements Echo { > Logger log = LoggerFactory.getLogger(this.getClass()); > > @Override > public String execute(String body) { > log.info( "{}:{} -> execute", this.getClass().getSimpleName(), > this.hashCode() ); > return body; > } > } > > > Blueprint Registering the service (service-one bundle): > <?xml version="1.0" encoding="UTF-8"?> > <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 > http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> > > <service interface="com.pronoia.test.osgi.service.Echo" > > <service-properties> > <entry key="instance" value="one" /> > </service-properties> > <bean class="com.pronoia.test.osgi.service.impl.EchoServiceOne" /> > </service> > > </blueprint> > > Java RouteBuilder (route-builder bundle): > public class VerySimpleBuilder extends RouteBuilder { > Echo blueprintServiceReference; > > @Override > public void configure() throws Exception { > from("timer://very-simple-builder?period=5000").routeId( > "very-simple-route" ) > .setBody( simple( "${exchangeProperty[" + > Exchange.TIMER_FIRED_TIME + "]}") ) > .log("Calling Service via Reference: ${body}" ) > .bean(blueprintServiceReference,false) > .to( "mock://result") > .log("Finished" ); > } > > public Echo getBlueprintServiceReference() { > return blueprintServiceReference; > } > > public void setBlueprintServiceReference(Echo blueprintServiceReference) { > this.blueprintServiceReference = blueprintServiceReference; > } > } > > Blueprint constructing the Camel context (camel-context bundle): > <?xml version="1.0" encoding="UTF-8"?> > <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > > xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0" > xsi:schemaLocation=" > http://www.osgi.org/xmlns/blueprint/v1.0.0 > http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd > http://camel.apache.org/schema/blueprint > http://camel.apache.org/schema/blueprint/camel-blueprint.xsd" >> > > <reference id="echo-service" > interface="com.pronoia.test.osgi.service.Echo" filter="instance=one" > timeout="2000" /> > > <bean id="very-simple-route-builder" > class="com.pronoia.test.camel.builder.VerySimpleBuilder"> > <property name="blueprintServiceReference" ref="echo-service" /> > </bean> > > <camelContext id="very-simple-context" > xmlns="http://camel.apache.org/schema/blueprint"> > <routeBuilder ref="very-simple-route-builder" /> > </camelContext> > > </blueprint> > >