How to dynamically update links in the OSGi component?

I have an OSGi component MyComponent.

This component has a link to the service MyService. Now MyServicehas a couple of implementations MyServiceImpl1and MyServiceImpl2. MyComponentalso has a property MyProperty.

Now I want that whenever MyPropertyequal to 1, MyComponent.MyServiceattached to MyServiceImpl1. And if I change MyPropertyto 2, it MyComponent.MyServicedynamically updates the binding MyServiceto `MyServiceImpl2.

How to do it? For reference, I use the Apache Felix container and prefer to avoid the lower level OSGi apis.

+4
source share
3 answers

- ".target". , , impl=1. impl=2.

@Component(property="impl=1")
public class MyServiceImpl1 implements MyService {
}
@Component(property="impl=2")
public class MyServiceImpl2 implements MyService {
}

:

@Component
public class MyComponent {
    @Reference(target="(impl=1)")
    volatile MyService myService;
}

1 2 , MyComponent myService.target . ( OSGi.)

1 2 ( select) MyComponent, . . MyComponent , select impl 1, 2? ,

@Designate( ocd=Config.class )
@Component( property = "select=1" )
public class MyComponent {
      static Class<?> types [] = {
          MyServiceImpl1.class,
          MyServiceImpl2.class,
      };
      @interface Config {
          int select() default 1;
      }

      @Reference(target="(|(impl=1)(impl=2))")
      volatile List<MyService> candidates;

      volatile MyService selected;

      @Activate
      @Modify
      void changed( Config config ) {
          Class<?> type = types[config.select()];
          Optional<MyService> service = candidates.
              stream().
              filter( type::isInstance ).
              findFirst();
          this.service = service.isPresent() ? service.get() : null;
      }
}

, , , . .

, , , . , , MyServiceImpl2 MyServiceImpl1 - , .

, , , 1 2 ? ?

( : )

+5

, MyService , (, ):

public interface MyService {
    public static final String TYPE = "myservice.type";
}

, OSGi Apache Felix, :

  • MyService MyComponent
    • Dynamic (policy = ReferencePolicy.DYNAMIC)
    • 1..n (cardinality = ReferenceCardinality.MANDATORY_MULTIPLE)
  • bind/unbind MyService MyComponent
  • Modified MyComponent

bind/unbind MyComponent MyService Felix SCR. .

Modified , - MyComponent. , , .

Felix SCR.

@Component (metatype = true, immediate = true)
@Service (value = MyComponent.class)
public class MyComponent {
    @Property(name = "impl.selector", value = "impl_1")
    private String implSelector = "impl_1";

    @Reference(
        referenceInterface = MyService.class,
        policy = ReferencePolicy.DYNAMIC,
        cardinality = ReferenceCardinality.MANDATORY_MULTIPLE,
        strategy = ReferenceStrategy.EVENT,
        bind = "bindService",
        unbind = "unbindService"
    )

    private Map<String, MyService> availableMyServiceImpls = new HashMap<String, MyService>();
    private MyService service = null;

    @Activate
    public void activate(ComponentContext componentContext) {
        service = availableMyServiceImpls.get(implSelector);
    }

    @Deactivate
    public void deactivate(ComponentContext componentContext) {
        availableMyServiceImpls.clear();
    }

    public void bindService(MyService serviceRef, Map<?,?> refProperties) {
        String serviceImplName = (String) refProperties.get(MyService.NAME_PROPERTY);
        availableMyServiceImpls.put(serviceImplName, serviceRef);
    }

    public void unbindService(MyService serviceRef, Map<?,?> refProperties) {
        String serviceImplName = (String) refProperties.get(MyService.NAME_PROPERTY);
        availableMyServiceImpls.remove(serviceImplName);
    }

    @Modified
    public void modified(ComponentContext componentContext) {
        Dictionary<String, Object> componentProps = componentContext.getProperties();
        implSelector = PropertiesUtil.toString(componentProps.get("impl.selector"), "");
        service = availableMyServiceImpls.get(implSelector);
    }
}
+2

-, , . ServiceReference , bundleContext.getServiceReferences().

(DS, iPojo, none,...).

+1

All Articles