Can't bind service with filter of requiring component which includes more dependencies in iPOJO

114 Views Asked by At

I have 3 component (A,B,C) providing services (As,As,Cs) (A and B implement the same (As) service). and 1 component (E) requiring service.

The component class of E, i declared:

@Component 
@.....
class E {
    @requires
    As dep1,
}

I have a controller to set a filter of "dep1". It controls "dep1" choosing the (As) service of components, A or B.

All components work fine. and i can control As service between A and B component.

Now, I modify the class E following:

@Component 
@.....
class E {
    @requires
    As dep1;
    @requires 
    Cs dep2;
}

In this case, i can also control the filter from a controller but :

"dep1" uses always service of component "A", in spite of the filter of "dep1" sets to "B"

How to resolve this case, please? Thanks in advance.

1

There are 1 best solutions below

0
On

I don’t know why it does not work fine if I don’t use resetLocalCache in controller component. This is my program

  1. A Component uses services

@Component(name="callHello", immediate=true)

@Instantiate
public class CallHello {

    @Requires(filter="(name.instance=A)")
    DelayService delayService;
    @Requires
    DirectService directService;
    public CallHello() {
    ...
        Label lb = new Label();
        Button bt = new Button("Printer 1");
        pn.add(bt);
        bt.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            if (directService != null)
            lb.setText(delayService.informDelay(tf.getText()));
                    }
        });
       ...
    }
    }
  1. Controller component

    @Component(name="Controller", immediate=true)

    @Instantiate

    public class ReconfigurationController {

     ...
    public ReconfigurationController() {
    
        fr = new JFrame("Controller");
        fr.setSize(350,150);
        ...
        final Button bt2 = new Button("To 2");
        bt2.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            if (chk2) {
                if (changeConnector(ctx, "hello.call.CallHello", "hello", "delayService", "B")) {
                    bt2.setLabel("To 1");
                    chk2 = false;
                }
            } else { 
                if (changeConnector(ctx, "hello.call.CallHello", "hello", "delayService", "A")) {
                    bt2.setLabel("To 2");
                    chk2 = true;
                }
            }
        }});
    ...
    public boolean changeConnector(BundleContext ctx, String componentName, String srcInstanceName, String dependencyName, String dstInstanceName) {
        boolean result = false;
        ServiceReference[] references;
        try {
            references = ctx.getServiceReferences(Factory.class.getName()," (factory.name="+componentName+")"); 
            Factory fact = (Factory)ctx.getService(references[0]);
    
            InstanceManager im = (InstanceManager) fact.getInstances().get(0);
            for(ComponentInstance ci: fact.getInstances()) {
            //System.out.println(ci.getInstanceName());
            if (ci.getInstanceName().equals(srcInstanceName) ) {
                im = (InstanceManager)ci;
            }
        }
        DependencyHandler handler = (DependencyHandler) im.getHandler("org.apache.felix.ipojo:requires");
        Dependency[] deps = handler.getDependencies();
        for (Dependency d : deps ) {
            // Lookup your dependency from deps (by id, by specification…)
            if (d.getField().equals(dependencyName)) {
                String srcFilter = d.getFilter();
                Filter filter = FrameworkUtil.createFilter("(instance.name="+dstInstanceName+")");
                d.setFilter(filter);
    
                if (d.getState() == 1) {
                    result = true;
                    d.resetLocalCache();
                } else {
                    System.out.println("rollback");
                    filter = FrameworkUtil.createFilter(srcFilter);
                    //d.setFilter(filter);
                    result = false;
                }
            }
        }
    } catch (InvalidSyntaxException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return result;
    }
    

    }

  2. I have 2 component instances (A and B)which provide service “informDelay”