RpcProviderService
instead@Deprecated public interface RpcProviderRegistry extends RpcConsumerRegistry, org.opendaylight.controller.md.sal.common.api.routing.RouteChangePublisher<RpcContextIdentifier,org.opendaylight.yangtools.yang.binding.InstanceIdentifier<?>>
There are 2 types of RPCs:
An RPC is global if there is intended to be only 1 registered implementation. A global RPC is not explicitly declared as such, essentially any RPC that is not defined to be routed is considered global.
Global RPCs are registered using the
addRpcImplementation(Class, RpcService)
method.
MD-SAL supports routing of RPC between multiple implementations where the appropriate implementation is selected at run time based on the content of the RPC message as described in YANG model.
RPC routing is based on:
InstanceIdentifier
value
which is part of the RPC input. This value is used to select the correct
implementation at run time.
A context type is modeled in YANG using a combination of a YANG identity
and Opendaylight specific extensions from yang-ext
module. These extensions are:
identity
.
Instance identifiers that reference these nodes are valid route identifiers for RPCs that
reference this context type.instance-identifier
as a reference to the particular context type defined by the
specified context identity
. The value of this
leaf is used by the RPC broker at run time to route the RPC request to the correct implementation.
Note that context-reference
may only be used on leaf elements of type
instance-identifier
or a type derived from instance-identifier
.
The following snippet declares a simple YANG identity
named example-context
:
module example {
...
identity example-context {
description "Identity used to define an example-context type";
}
...
}
We then use the declared identity to define a context type by using it in combination
with the context-instance
YANG extension. We'll associate the context type
with a list element in the data tree. This defines the set of nodes whose instance
identifiers are valid for the example-context
context type.
The following YANG snippet imports the yang-ext
module and defines the list
element named item
inside a container named foo
:
module foo {
...
import yang-ext {prefix ext;}
...
container foo {
list item {
key "id";
leaf id {type string;}
ext:context-instance "example-context";
}
}
...
}
The statement ext:context-instance "example-context";
inside the list element
declares that any instance identifier referencing item
in the data
tree is valid for example-context
. For example, the following instance
identifier:
InstanceIdentifier.create(Foo.class).child(Item.class,new ItemKey("Foo"))is valid for
example-context
. However the following:
InstanceIdentifier.create(Example.class)is not valid.
So using an identity
in combination with context-instance
we
have effectively defined a context type that can be referenced in a YANG RPC input.
To define an RPC to be routed based on the context type we need to add an input leaf element that references the context type which will hold an instance identifier value to be used to route the RPC.
The following snippet defines an RPC named show-item
with 2 leaf elements
as input: item
of type instance-identifier
and description
:
module foo { ... import yang-ext {prefix ext;} ... rpc show-item { input { leaf item { type instance-identifier; ext:context-reference example-context; } leaf description { type "string"; } } } }
We mark the item
leaf with a context-reference
statement that
references the example-context
context type. RPC calls will then be routed
based on the instance identifier value contained in item
. Only instance
identifiers that point to a foo/item
node are valid as input.
The generated RPC Service interface for the module is:
interface FooService implements RpcService { Future<RpcResult<Void>> showItem(ShowItemInput input); }
For constructing the RPC input, there are generated classes ShowItemInput and ShowItemInputBuilder.
To register a routed implementation for the show-item
RPC, we must use the
addRoutedRpcImplementation(Class, RpcService)
method. This
will return a BindingAwareBroker.RoutedRpcRegistration
instance which can then be used to register /
unregister routed paths associated with the registered implementation.
The following snippet registers myImpl
as the RPC implementation for an
item
with key "foo"
:
// Create the instance identifier path for item "foo" InstanceIdentifier path = InstanceIdentifier.create(Foo.class).child(Item.class, new ItemKey("foo")); // Register myImpl as the implementation for the FooService RPC interface RoutedRpcRegistration reg = rpcRegistry.addRoutedRpcImplementation(FooService.class, myImpl); // Now register for the context type and specific path ID. The context type is specified by the // YANG-generated class for the example-context identity. reg.registerPath(ExampleContext.class, path);
It is also possible to register the same implementation for multiple paths:
InstanceIdentifier one = InstanceIdentifier.create(Foo.class).child(Item.class, new ItemKey("One")); InstanceIdentifier two = InstanceIdentifier.create(Foo.class).child(Item.class, new ItemKey("Two")); RoutedRpcRegistration reg = rpcRegistry.addRoutedRpcImplementation(FooService.class, myImpl); reg.registerPath(ExampleContext.class, one); reg.registerPath(ExampleContext.class, two);
When another client invokes the showItem(ShowItemInput)
method on the proxy instance
retrieved via RpcConsumerRegistry.getRpcService(Class)
, the proxy will inspect the
arguments in ShowItemInput, extract the InstanceIdentifier value of the item
leaf and select
the implementation whose registered path matches the InstanceIdentifier value of the item
leaf.
The generated interfaces require implementors to return
Future
<RpcResult
<{RpcName}Output>> instances.
Implementations should do processing of RPC calls asynchronously and update the
returned Future
instance when processing is complete.
However using Futures.immediateFuture
is valid only if the result is immediately available and asynchronous processing is unnecessary and
would only introduce additional complexity.
The RpcResult
is a generic
wrapper for the RPC output payload, if any, and also allows for attaching error or
warning information (possibly along with the payload) should the RPC processing partially
or completely fail. This is intended to provide additional human readable information
for users of the API and to transfer warning / error information across the system
so it may be visible via other external APIs such as Restconf.
It is recommended to use the RpcResult
for conveying appropriate error information
on failure rather than purposely throwing unchecked exceptions if at all possible.
While unchecked exceptions will fail the returned Future
,
using the intended RpcResult to convey the error information is more user-friendly.
Modifier and Type | Method and Description |
---|---|
<T extends org.opendaylight.yangtools.yang.binding.RpcService> |
addRoutedRpcImplementation(Class<T> serviceInterface,
T implementation)
Deprecated.
Registers an implementation of the given routed RPC service interface.
|
<T extends org.opendaylight.yangtools.yang.binding.RpcService> |
addRpcImplementation(Class<T> serviceInterface,
T implementation)
Deprecated.
Registers a global implementation of the provided RPC service interface.
|
getRpcService
<T extends org.opendaylight.yangtools.yang.binding.RpcService> BindingAwareBroker.RpcRegistration<T> addRpcImplementation(Class<T> serviceInterface, T implementation) throws IllegalStateException
serviceInterface
- the YANG-generated interface of the RPC Service for which to register.implementation
- "the implementation of the RPC service interface.BindingAwareBroker.RpcRegistration.close()
.IllegalStateException
- if the supplied RPC interface is a routed RPC type.<T extends org.opendaylight.yangtools.yang.binding.RpcService> BindingAwareBroker.RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> serviceInterface, T implementation) throws IllegalStateException
See the class
documentation for information and example on
how to use routed RPCs.
serviceInterface
- the YANG-generated interface of the RPC Service for which to register.implementation
- the implementation instance to register.BindingAwareBroker.RpcRegistration.close()
should be called to unregister the implementation
and all previously registered paths when no longer needed.IllegalStateException
- if the supplied RPC interface is not a routed RPC type.Copyright © 2018 OpenDaylight. All rights reserved.