Ask is moving to Stack Overflow and Serverfault.com! Please use the "opendaylight" tag on either of these sites. This site is now in Read-Only mode

0

No implementation of RPC AbsoluteSchemaPath{path=[(PACKAGE)METHOD]} available)

asked 2017-08-15 17:22:13 -0800

VincentJahjah gravatar image

updated 2017-08-16 07:22:36 -0800

I get this problem when sending a REST request to my costum-made RPC methods. Note that the methods I am trying to use show up in yangman, meaning they are at integrated up to some point in the process. To be sure, other people have had this form of problem in the past:

https://ask.opendaylight.org/question/13341/i-have-yangui-problemno-implementation-of-rpc-absoluteschemapathpathurnopendaylightparamsxmlnsyanghellorevision2015-01-05hello-world-available/
https://ask.opendaylight.org/question/14218/no-implementation-of-rpc-absoluteschemapath-in-boron-when-using-httpclient/
https://ask.opendaylight.org/question/5960/how-to-register-salflowservice-to-prevent-domrpcimplementationnotavailableexception-no-implementation-of-rpc/
https://ask.opendaylight.org/question/13364/application-development-tutorial-error-while-running-hello-world/
https://ask.opendaylight.org/question/13666/i-am-getting-this-error-while-implementing-hello-world-on-yang-ui-pleasehelp/

The apparent cause is that the class providing the implementation is NOT registered as providing the implementation for those RPC calls. I have seen two ways of solving the problem, which appear to ultimately do the same thing. I will call them the "old way" and the "current way". I have tried both, but I still get the same error. Here is my yang file:

module hash-load-balancer-manager {
    ...
    rpc make-hashing-switch {
        input {...}
    }

    rpc remove-hashing-switch {
        input { ... }
    }
}

The OLD WAY

Declare and distribute the rpc registration provider from the bluepring xml file:

<?xml version="1.0" encoding="UTF-8"?>
<blueprint odl:use-default-for-reference-types="true" xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
    ...
    <reference interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry" id="rpcRegistry"/>
    ...
    <bean id="hashLoadBalancerManagerImpl" destroy-method="close" init-method="init" class="edu.ulaval.sdn.hashloadbalancermanager.HashLoadBalancerManagerImpl">
        ...
        <argument ref="rpcRegistry"/>
    </bean>
</blueprint>

Then handle the registration on initialization:

public class HashLoadBalancerManagerImpl implements HashLoadBalancerManagerService, ... {
    ...
    private RpcProviderRegistry rpcProviderRegistry;
    private RpcRegistration<HashLoadBalancerManagerService> serviceRegistration;
    ...
    public HashLoadBalancerManagerImpl(RpcProviderRegistry rpcProviderRegistry) {
        ...
        this.rpcProviderRegistry = rpcProviderRegistry;
    }
    ...
    public void init() {
        LOG.info("Initializing...");
        serviceRegistration = rpcProviderRegistry.addRpcImplementation(HashLoadBalancerManagerService.class, this);
        ...
    }

    /** Implemented from the AutoCloseable interface. */
    @Override
    public void close() {
        LOG.info("Closing...");
        serviceRegistration.close();
        ...
    }
    ...
    @Override
    public Future<RpcResult<Void>> removeHashingSwitch(RemoveHashingSwitchInput input) {
        LOG.info("removing hash load balancer {}", input.getNodeId());
        ...
    }
    ... (and so on)
}

THE CURRENT WAY

Simply handle the registration automatically via the blueprint file, using ODL's special tags:

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
           odl:use-default-for-reference-types="true">
  ...
  <bean id="hashLoadBalancerManagerImpl" class="edu.ulaval.sdn.hashloadbalancermanager.HashLoadBalancerManagerImpl" init-method="init" destroy-method="close">
     ... NOTHING OF IMPORTANCE HERE ...
  </bean>

  <odl:rpc-implementation ref="hashLoadBalancerManagerImpl"/>
</blueprint>

Now what?

Why is my rpc method still not registered? I tried the following command to search the LOGs:

log:display | grep Balancer

Nothing shows up. At the very least the plugin should be "init". I can confirm that OpenFlowPlugin's LLDPSpeaker is built using this method,so why is my plugin not logging anything?

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2017-08-17 11:27:59 -0800

VincentJahjah gravatar image

updated 2017-08-25 07:14:12 -0800

Answering my own question.

I went back to the early steps of my code where I recalled that the RPC methods were registering correctly. I slowly rebuilt my code up to the current state, incrementally verifying that the added changes were not the changes that broke the RPC registration. I singled out the one line in the init method:

public void init() {
    LOG.info("Initializing...");
    registerAsDataChangeListener(dataBroker);
    // THIS LINE: Preconditions.checkNotNull(salFlowService, "sal flow service must be set");
    Preconditions.checkNotNull(notificationProvider, "notification provider must be set");
    Preconditions.checkNotNull(dataBroker, "dataBroker must be set");
    allNodes = getAllNodes();
    hashFlowInstaller = new HashFlowInstaller(LOG, salFlowService);
    LOG.debug("Got all nodes: {}", allNodes.size());
}

Indeed, with this line, the RPC call is NOT registered, and without this line, the RPC call IS registered. Presumably there were other glitches in my code, but I have boiled it down to this.

It turns out I forgot to include SalFlowService references in my blueprint. Worryingly, though, the Preconditions clause did not prevent other parts of the plugin from running, yet no LOGs were received, making the failure completely opaque.

EDIT Adding SalFlowService to the blueprint is sufficient to make the registration fail. Uncommenting the lines in the blueprint, makes the registration fail:

  <!-- <odl:rpc-service id="salFlowService" interface="org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService" /> -->

  <!-- Create the OpendaylightToaster instance and inject its dependencies -->
  <bean id="hashLoadBalancerManagerImpl" class="edu.ulaval.sdn.hashloadbalancermanager.HashLoadBalancerManagerImpl" init-method="init" destroy-method="close">
    <property name="dataBroker" ref="dataBroker"/>
    <property name="notificationProvider" ref="notificationService"/>
    <!-- <property name="salFlowService" ref="salFlowService" /> -->
  </bean>

EDIT 2 I removed SalFlowService from the code, yet its existence in the blueprint file causes the service registration to fail. It feels to me that the culprit is the blueprint file, as it is responsible for registering rpc services. If including salFlowService makes the blueprint processing fail, it would explain why the rpc registration failed in the first place. I am not entirely clear on what "odl:rpc-service" does here. I am using it only because that is how salFlowService is being imported in other segments of ODL's code (e.g. l2Switch).

EDIT 3: Fixed it The blueprint was indeed failing to apply DI correctly, which caused the registration to fail (presumably because if DI fails at any point, blueprint parsing immediately stops). My problem was that I asked for the DI to inject the property "salFlowService", but I did not create a setter:

public void setSalFlowService(SalFlowService salFlowService) {
    this.salFlowService = salFlowService;
}

This meant the DI plugins could not inject anything, leading to failure. If I had used constructor arguments, this would not have been necessary.

Takeaways If anything in the blueprint fails, it may do nothing in terms of rpc registration. If a call to "Preconditions.checkNotNull" fails, rpc registration might also fail. If registration fails, logging may not work.

edit flag offensive delete publish link more

Comments

I encountered this problem again, and this time it was the dependency versions I used which appeared to cause the RPC unimplemented problem. I essentially upgrade from l2switch 0.6.0-SNAPSHOT to 0.7.0-SNAPSHOT, and then things broke. (I also updated all other dependencies, like in l2switch)

VincentJahjah ( 2017-08-30 05:50:02 -0800 )edit

I encountered this problem again, and as far as I can tell, it was because I put ANY code under the yang "model" projects. Moving the code to a separate project fixed the problem.

VincentJahjah ( 2017-10-06 18:07:00 -0800 )edit
Login/Signup to Answer

Question Tools

Follow
1 follower

Stats

Asked: 2017-08-15 17:22:13 -0800

Seen: 117 times

Last updated: Aug 25