camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Siano, Stephan" <stephan.si...@sap.com>
Subject RE: Invoking Dynamic OSGi Blueprint services from a Java RouteBuilder
Date Wed, 27 Jan 2016 06:52:12 GMT
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.siano@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:quinn@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>


Mime
View raw message