Uploaded image for project: 'Felix'
  1. Felix
  2. FELIX-5862

Bind a Service with an configurable target/placeholder in @Referance annotation

    XMLWordPrintableJSON

Details

    • New Feature
    • Status: Closed
    • Major
    • Resolution: Not A Bug
    • scr-2.1.0
    • None
    • None

    Description

      Hello,

      my Component ServiceA exists one for each configuration. (foo and bar)

       

      @Component(service = ServiceA.class, immediate = true)
      @Designate(factory = true, ocd = ConfigA.class)
      public class ServiceA {
      
        @ObjectClassDefinition
        public @interface ConfigA {
      
          String ident();
        }
      
        private ConfigA config;
      
        private void activate(ConfigA config) {
          this.config = config;
          System.out.println("ServiceA activated with ident: " + config.ident());
      
        }
      
        public String getIdent() {
          return config.ident();
        }
      }
      
      ---
          "my.test.cfgservicetest.ServiceA~foo": {\
              "ident:String": "foo"\
          },\
          "my.test.cfgservicetest.ServiceA~bar": {\
              "ident:String": "bar"\
          },\
      

       

       

      When i use a static target filter "(ident=foo)" felix could find the correct service by because the value is set in Component Configuration Properties.

      @Component(service = ServiceB.class, immediate = true)
      public class ServiceB {
      
        @Reference(target = "(ident=foo)")
        public void bindServiceA(ServiceA serviceA) {
          System.out.println("Service B -> Service A (ident): " + serviceA.getIdent());
        }
      }
      

       

      It would be great if there is a more flexible way, using a placeholder like $CCP

      {serviceARefIdent} in the targetfilter. When Felix tryes bind the ServiceA to ServiceC it could lookup for the *C*omponent *C*onfiguration *P*roperties of ServiceC and replace the placeholder in the target filter before searching fore the right ServiceA.

       

      
      

      @Component(service = ServiceC.class, immediate = true)
      @Designate(factory = true, ocd = ConfigC.class)
      public class ServiceC {

        @ObjectClassDefinition
        public @interface ConfigC {     String serviceARefIdent();   }

        private ConfigC config;


        @Reference(target = "(ident=$CCP{serviceARefIdent}

      )")
        public void bindServiceA(ServiceA serviceA)

      {     System.out.println("Service B -> Service A (ident): " + serviceA.getIdent());   }

      }
      — config
      "my.test.cfgservicetest.ServiceC~foo":

      {\ "serviceARefIdent:String": "foo"\  }

      ,\
      "my.test.cfgservicetest.ServiceC~bar":

      {\         "serviceARefIdent:String": "bar"\ }

      {code}
       

      I couldn't find information about this in the OSGi Spec.

       

      Is there any way to do this at the moment?

      Is there a better way to bind 2 factory-configured services to each other (without Servicetracker)?

      Is there any way to add this to Felix SCR(direct or as kind of scr-plugin?)

       

      It also would be nice to filter with SystemEnviromentPropertys

        @Reference(target = "(ident=$ENV{serviceARefIdent})")
      

       

       

       

      Regards

      Stefan

      Attachments

        Activity

          People

            Unassigned Unassigned
            bischofs@jena.de Stefan Bischof
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: