Interface RpcProviderRegistry
-
- All Superinterfaces:
BindingAwareService
,BindingService
,RouteChangePublisher<RpcContextIdentifier,InstanceIdentifier<?>>
,RpcConsumerRegistry
- All Known Subinterfaces:
BindingAwareBroker.ProviderContext
- All Known Implementing Classes:
AbstractBindingSalProviderInstance
,HeliumRpcProviderRegistry
,RootBindingAwareBroker
,RootBindingAwareBroker.RootSalInstance
@Deprecated(forRemoval=true) public interface RpcProviderRegistry extends RpcConsumerRegistry, RouteChangePublisher<RpcContextIdentifier,InstanceIdentifier<?>>
Deprecated, for removal: This API element is subject to removal in a future version.UseRpcProviderService
insteadProvides a registry for Remote Procedure Call (RPC) service implementations. The RPCs are defined in YANG models.There are 2 types of RPCs:
- Global
- Routed
Global RPC
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.Routed RPC
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:
- Route identifier -
An
InstanceIdentifier
value which is part of the RPC input. This value is used to select the correct implementation at run time. - Context Type - A YANG-defined construct which constrains the subset of valid route identifiers for a particular RPC.
Context type
A context type is modeled in YANG using a combination of a YANG
identity
and Opendaylight specific extensions fromyang-ext
module. These extensions are:- context-instance - This is used in the data tree part of a YANG model to
define a context type that associates nodes with a specified context
identity
. Instance identifiers that reference these nodes are valid route identifiers for RPCs that reference this context type. - context-reference - This is used in RPC input to mark a leaf of type
instance-identifier
as a reference to the particular context type defined by the specified contextidentity
. The value of this leaf is used by the RPC broker at run time to route the RPC request to the correct implementation. Note thatcontext-reference
may only be used on leaf elements of typeinstance-identifier
or a type derived frominstance-identifier
.
1. Defining a Context Type
The following snippet declares a simple YANG
identity
namedexample-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 theexample-context
context type.The following YANG snippet imports the
yang-ext
module and defines the list element nameditem
inside a container namedfoo
: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 referencingitem
in the data tree is valid forexample-context
. For example, the following instance identifier:InstanceIdentifier.create(Foo.class).child(Item.class,new ItemKey("Foo"))
is valid forexample-context
. However the following:InstanceIdentifier.create(Example.class)
is not valid.So using an
identity
in combination withcontext-instance
we have effectively defined a context type that can be referenced in a YANG RPC input.2. Defining an RPC to use the Context Type
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 typeinstance-identifier
anddescription
: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 acontext-reference
statement that references theexample-context
context type. RPC calls will then be routed based on the instance identifier value contained initem
. Only instance identifiers that point to afoo/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.
3. Registering a routed RPC implementation
To register a routed implementation for the
show-item
RPC, we must use theaddRoutedRpcImplementation(Class, RpcService)
method. This will return aBindingAwareBroker.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 anitem
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 viaRpcConsumerRegistry.getRpcService(Class)
, the proxy will inspect the arguments in ShowItemInput, extract the InstanceIdentifier value of theitem
leaf and select the implementation whose registered path matches the InstanceIdentifier value of theitem
leaf.
Notes for RPC Implementations
RpcResult
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 usingFutures.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 returnedFuture
, using the intended RpcResult to convey the error information is more user-friendly.
-
-
Method Summary
All Methods Instance Methods Abstract Methods Deprecated Methods Modifier and Type Method Description <T extends RpcService>
BindingAwareBroker.RoutedRpcRegistration<T>addRoutedRpcImplementation(Class<T> serviceInterface, T implementation)
Deprecated, for removal: This API element is subject to removal in a future version.Registers an implementation of the given routed RPC service interface.<T extends RpcService>
BindingAwareBroker.RpcRegistration<T>addRpcImplementation(Class<T> serviceInterface, T implementation)
Deprecated, for removal: This API element is subject to removal in a future version.Registers a global implementation of the provided RPC service interface.-
Methods inherited from interface org.opendaylight.controller.md.sal.common.api.routing.RouteChangePublisher
registerRouteChangeListener
-
Methods inherited from interface org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry
getRpcService
-
-
-
-
Method Detail
-
addRpcImplementation
<T extends RpcService> BindingAwareBroker.RpcRegistration<T> addRpcImplementation(Class<T> serviceInterface, T implementation) throws IllegalStateException
Deprecated, for removal: This API element is subject to removal in a future version.Registers a global implementation of the provided RPC service interface. All methods of the interface are required to be implemented.- Parameters:
serviceInterface
- the YANG-generated interface of the RPC Service for which to register.implementation
- "the implementation of the RPC service interface.- Returns:
- an RpcRegistration instance that should be used to unregister the RPC implementation
when no longer needed by calling
BindingAwareBroker.RpcRegistration.close()
. - Throws:
IllegalStateException
- if the supplied RPC interface is a routed RPC type.
-
addRoutedRpcImplementation
<T extends RpcService> BindingAwareBroker.RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> serviceInterface, T implementation) throws IllegalStateException
Deprecated, for removal: This API element is subject to removal in a future version.Registers an implementation of the given routed RPC service interface.See the
class
documentation for information and example on how to use routed RPCs.- Parameters:
serviceInterface
- the YANG-generated interface of the RPC Service for which to register.implementation
- the implementation instance to register.- Returns:
- a RoutedRpcRegistration instance which can be used to register paths for the RPC
implementation via invoking RoutedRpcRegistration#registerPath(Class, InstanceIdentifer).
BindingAwareBroker.RpcRegistration.close()
should be called to unregister the implementation and all previously registered paths when no longer needed. - Throws:
IllegalStateException
- if the supplied RPC interface is not a routed RPC type.
-
-