7 Replies Latest reply on Oct 17, 2011 6:39 AM by m.jimen.blazquez

    Invoking a method on an OSGi (Spring DM) Service via Camel

    mhuisking_michael.c.huisking

      (I'm posting this into the ESB forum, let me know if I should put it into MediationRouter/Camel instead.)

       

      ServiceMix Version 4.3.1-fuse-01-15, Dev/Test on Windows7, Deployment/Production to Solaris  JDK 1.6

       

      Hi,

       

      I don't think this is that much of a fringe case, but there really isn't that much information out there on invoking a method on a SpringDM Service.  (Since 2009 or so)

       

      From what I've read, this seems like it should be a real simple exercise:  Register the service with ServiceMix, and then just use a bean ref in a Camel route to invoke a method on the service.  When doing

      the binding Camel first looks in the OSGi service registry and then falls back to the regular registry (e.g. Spring ApplicationContextRegistry)  SO, I think I must be missing something...

       

      Let me set up an example using a service from a FuseSource training session.

       

      For the service, a very simple HelloWorld service, with 1 method

      -


      pom.xml

      <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <parent>
      <artifactId>osgi-exercises</artifactId>
      <groupId>com.fusesource</groupId>
      <version>0.0.1-SNAPSHOT</version>
      </parent>
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.fusesource</groupId>
      <artifactId>osgi-exercises-hello-world-bundle</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>bundle</packaging>
      <name>osgi-exercises-hello-world-bundle</name>
      
      <build>
      <resources>
      <resource>
      <directory>src/main/resources</directory>
      </resource>
      </resources>
      
      <plugins>
      <plugin>
      <groupId>org.apache.felix</groupId>
      <artifactId>maven-bundle-plugin</artifactId>
      <extensions>true</extensions>
      <version>1.4.0</version>
      <configuration>
      <instructions>
      <Export-Package>
      !com.fusesource.training.osgi.helloworld.internal,
      com.fusesource.training.osgi.helloworld*
      </Export-Package>
      <Private-Package>
      com.fusesource.training.osgi.helloworld.internal
      </Private-Package>
      <Import-Package>*</Import-Package>
      <Include-Resource>src/main/resources</Include-Resource>
      </instructions>
      </configuration>
      </plugin>
      </plugins>
      </build>
      </project>
      

      -


      A HelloWorld Interface

      package com.fusesource.training.osgi.helloworld;
      
      public interface HelloWorld {
      String sayHello(String message);
      }
      

      -


      HelloWorld Implementation

      package com.fusesource.training.osgi.helloworld.internal;
      
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import org.springframework.beans.factory.DisposableBean;
      import org.springframework.beans.factory.InitializingBean;
      
      import com.fusesource.training.osgi.helloworld.HelloWorld;
      
      public class HelloWorldImpl implements HelloWorld, InitializingBean, DisposableBean {
      
      public static final Logger logger = LoggerFactory.getLogger(HelloWorldImpl.class);
      
      private String response; 
      
      public String sayHello(String message) {
      logger.info("Just got message '" + message + "'");
      logger.info("Returning... '" + response + "'");
      return response;
      }
      
      public void setResponse(String response) {
      logger.info("Setting the response to '" + response + "'");
      this.response = response;
      }
      
      public void afterPropertiesSet() throws Exception {
      logger.info("HelloWorldImpl initialized.");
      logger.info("Will return response '" + response + "'");
      }
      
      public void destroy() throws Exception {
      logger.info("Shutting down HelloWorldImpl");
      }
      
      }
      
      

       

      -


      Spring Bundle Context (bundle-context.xml)

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="
      http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans.xsd">
      
      <!-- regular spring configuration file defining the beans for this
      bundle. The configuration of OSGi definitions is kept in a separate 
      configuration file so that this file can easily be used
      for integration testing outside of an OSGi environment -->
      
      <bean id="helloWorld" 
      class="com.fusesource.training.osgi.helloworld.internal.HelloWorldImpl">
      <property name="response" value="${response}"></property>
      </bean>
      </beans>
      

      -


      OSGi Bundle Context (bundle-context-osgi.xml)

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:osgi="http://www.springframework.org/schema/osgi"
      xmlns:osgix="http://www.springframework.org/schema/osgi-compendium"
      xmlns:ctx="http://www.springframework.org/schema/context"
      
      xsi:schemaLocation="
      http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/context 
      http://www.springframework.org/schema/context/spring-context.xsd
      http://www.springframework.org/schema/osgi 
      http://www.springframework.org/schema/osgi/spring-osgi.xsd
      http://www.springframework.org/schema/osgi-compendium 
      http://www.springframework.org/schema/osgi-compendium/spring-osgi-compendium.xsd" >
      
      <osgix:cm-properties id="helloworld.cfg.with.defaults" persistent-id="helloworld">
      <prop key="response">Right back at ya</prop>
      </osgix:cm-properties>
      
      <!-- placeholder configurer -->
      <ctx:property-placeholder properties-ref="helloworld.cfg.with.defaults"></ctx:property-placeholder>
      
      <osgi:service id="helloService" ref="helloWorld" interface="com.fusesource.training.osgi.helloworld.HelloWorld"></osgi:service>
      </beans>
      

       

       

      -


      So, I install and start this bundle. 

       

      karaf@root&gt; osgi:ls 203

       

      osgi-exercises-hello-world-bundle (203) provides:

       

      org.springframework.osgi.bean.name = helloWorld

      Bundle-SymbolicName = com.fusesource.osgi-exercises-hello-world-bundle

      Bundle-Version = 0.0.1.SNAPSHOT

      objectClass = com.fusesource.training.osgi.helloworld.HelloWorld

      service.id = 277

       

      org.springframework.context.service.name = com.fusesource.osgi-exercises-hello-world-bundle

      Bundle-SymbolicName = com.fusesource.osgi-exercises-hello-world-bundle

      Bundle-Version = 0.0.1.SNAPSHOT

      objectClass = org.springframework.osgi.context.DelegatedExecutionOsgiBundleApplicationContext,

      org.springframework.osgi.context.ConfigurableOsgiBundleApplicationContext,

      org.springframework.context.ConfigurableApplicationContext, org.springframework.context.ApplicationContext,

      org.springframework.context.Lifecycle, org.springframework.beans.factory.ListableBeanFactory,

      org.springframework.beans.factory.HierarchicalBeanFactory, org.springframework.context.MessageSource,

      org.springframework.context.ApplicationEventPublisher, org.springframework.core.io.support.ResourcePatternResolver,

      org.springframework.beans.factory.BeanFactory, org.springframework.core.io.ResourceLoader,

      org.springframework.beans.factory.DisposableBean

      service.id = 279

       

      -


      At this point, I just want to make another bundle with a really simple Camel route that calls "sayHello()"

       

      This project might be a bit off -- I just tweaked a pom real quick for this example.

       

      pom.xml

      <?xml version="1.0" encoding="UTF-8"?>
      <!--
      ~ Copyright 2011 FuseSource
      ~
      ~    Licensed under the Apache License, Version 2.0 (the "License");
      ~    you may not use this file except in compliance with the License.
      ~    You may obtain a copy of the License at
      ~
      ~        http://www.apache.org/licenses/LICENSE-2.0
      ~
      ~    Unless required by applicable law or agreed to in writing, software
      ~    distributed under the License is distributed on an "AS IS" BASIS,
      ~    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      ~    See the License for the specific language governing permissions and
      ~    limitations under the License.
      -->
      
      <project xmlns="http://maven.apache.org/POM/4.0.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      
      <groupId>com.fusesource</groupId>
      <artifactId>sample_camel_route</artifactId>
      <packaging>bundle</packaging>
      <name>osgi-exercises :: Camel Route</name>
      <description>Camel Route Consumer for Simple OSGi Service</description>
      <version>0.0.1-SNAPSHOT</version>
      
      <properties>
      <camel.version>2.6.0-fuse-01-09</camel.version>
      </properties>
      
      <build>
      <defaultGoal>install</defaultGoal>
      <plugins>
      <plugin>
      <groupId>org.apache.felix</groupId>
      <artifactId>maven-bundle-plugin</artifactId>
      <extensions>true</extensions>
      <configuration>
      <instructions>
      <Import-Package>
      *,
      org.apache.servicemix.nmr.api
      </Import-Package>
      </instructions>
      </configuration>
      </plugin>
      </plugins>
      </build>
      
      <dependencies>
      <dependency>
      <groupId>org.apache.camel</groupId>
      <artifactId>camel-spring</artifactId>
      <version>${camel.version}</version>
      </dependency>
      </dependencies>
      </project>
      

      -


      Camel Context

      <?xml version="1.0" encoding="UTF-8"?>
      
      <!--
      ~ Copyright 2011 FuseSource
      ~
      ~    Licensed under the Apache License, Version 2.0 (the "License");
      ~    you may not use this file except in compliance with the License.
      ~    You may obtain a copy of the License at
      ~
      ~        http://www.apache.org/licenses/LICENSE-2.0
      ~
      ~    Unless required by applicable law or agreed to in writing, software
      ~    distributed under the License is distributed on an "AS IS" BASIS,
      ~    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      ~    See the License for the specific language governing permissions and
      ~    limitations under the License.
      -->
      
      <beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:camel="http://camel.apache.org/schema/spring"
      xmlns:osgi="http://www.springframework.org/schema/osgi"
      xmlns:typ="http://examples.fusesource.com/payment-service/types"
      xsi:schemaLocation="
      http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/osgi
      http://www.springframework.org/schema/osgi/spring-osgi.xsd
      http://camel.apache.org/schema/spring
      http://camel.apache.org/schema/spring/camel-spring.xsd
      ">
      
      <camel:camelContext>
      <camel:route>
      <camel:from uri="direct:start"></camel:from>
      <camel:bean ref="helloWorld" method="sayHello"></camel:bean>
      </camel:route>
      </camel:camelContext>
      </beans>
      

      -


      "helloWorld" can't be resolved.  Am I missing a piece to link helloWorld to helloWorld Service? (In the sample_camel_route bundle)  Are my namespaces screwed up?  Or, should I just be using nmr for any kind of inter-bundle communication in ServiceMix?

       

      Perhaps from what I learn I can tweak the out of date OSGi example on the Apache Camel website.

       

      Thanks in advance,

      Mick

       

      Edited by: mhuisking on Jul 22, 2011 12:29 PM Fixed Formatting