Reuse singleLayer boolean
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / rpc / RpcContextImpl.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.openflowplugin.impl.rpc;
9
10 import com.google.common.collect.ImmutableClassToInstanceMap;
11 import com.google.common.util.concurrent.Futures;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import java.util.Set;
14 import java.util.concurrent.Semaphore;
15 import java.util.concurrent.atomic.AtomicLong;
16 import org.eclipse.jdt.annotation.NonNull;
17 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
18 import org.opendaylight.mdsal.binding.api.RpcProviderService;
19 import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
20 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
21 import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
22 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
23 import org.opendaylight.openflowplugin.api.openflow.lifecycle.ContextChainMastershipState;
24 import org.opendaylight.openflowplugin.api.openflow.lifecycle.ContextChainMastershipWatcher;
25 import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
26 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
27 import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
28 import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProviderFactory;
29 import org.opendaylight.openflowplugin.impl.services.SendEchoImpl;
30 import org.opendaylight.openflowplugin.impl.services.sal.AddBundleMessagesImpl;
31 import org.opendaylight.openflowplugin.impl.services.sal.AddFlowImpl;
32 import org.opendaylight.openflowplugin.impl.services.sal.AddFlowsBatchImpl;
33 import org.opendaylight.openflowplugin.impl.services.sal.AddGroupImpl;
34 import org.opendaylight.openflowplugin.impl.services.sal.AddGroupsBatchImpl;
35 import org.opendaylight.openflowplugin.impl.services.sal.AddMeterImpl;
36 import org.opendaylight.openflowplugin.impl.services.sal.AddMetersBatchImpl;
37 import org.opendaylight.openflowplugin.impl.services.sal.ControlBundleImpl;
38 import org.opendaylight.openflowplugin.impl.services.sal.ProcessFlatBatchImpl;
39 import org.opendaylight.openflowplugin.impl.services.sal.RemoveFlowImpl;
40 import org.opendaylight.openflowplugin.impl.services.sal.RemoveFlowsBatchImpl;
41 import org.opendaylight.openflowplugin.impl.services.sal.RemoveGroupImpl;
42 import org.opendaylight.openflowplugin.impl.services.sal.RemoveGroupsBatchImpl;
43 import org.opendaylight.openflowplugin.impl.services.sal.RemoveMeterImpl;
44 import org.opendaylight.openflowplugin.impl.services.sal.RemoveMetersBatchImpl;
45 import org.opendaylight.openflowplugin.impl.services.sal.SendBarrierImpl;
46 import org.opendaylight.openflowplugin.impl.services.sal.SendExperimenterImpl;
47 import org.opendaylight.openflowplugin.impl.services.sal.SendExperimenterMpRequestImpl;
48 import org.opendaylight.openflowplugin.impl.services.sal.SetConfigImpl;
49 import org.opendaylight.openflowplugin.impl.services.sal.TransmitPacketImpl;
50 import org.opendaylight.openflowplugin.impl.services.sal.UpdateFlowImpl;
51 import org.opendaylight.openflowplugin.impl.services.sal.UpdateFlowsBatchImpl;
52 import org.opendaylight.openflowplugin.impl.services.sal.UpdateGroupImpl;
53 import org.opendaylight.openflowplugin.impl.services.sal.UpdateGroupsBatchImpl;
54 import org.opendaylight.openflowplugin.impl.services.sal.UpdateMeterImpl;
55 import org.opendaylight.openflowplugin.impl.services.sal.UpdateMetersBatchImpl;
56 import org.opendaylight.openflowplugin.impl.services.sal.UpdatePortImpl;
57 import org.opendaylight.openflowplugin.impl.services.sal.UpdateTableImpl;
58 import org.opendaylight.openflowplugin.impl.services.singlelayer.GetAsyncImpl;
59 import org.opendaylight.openflowplugin.impl.services.singlelayer.SetAsyncImpl;
60 import org.opendaylight.openflowplugin.impl.statistics.services.GetAggregateFlowStatisticsFromFlowTableForGivenMatchImpl;
61 import org.opendaylight.openflowplugin.impl.statistics.services.GetAllGroupStatisticsImpl;
62 import org.opendaylight.openflowplugin.impl.statistics.services.GetAllMeterConfigStatisticsImpl;
63 import org.opendaylight.openflowplugin.impl.statistics.services.GetAllMeterStatisticsImpl;
64 import org.opendaylight.openflowplugin.impl.statistics.services.GetAllNodeConnectorsStatisticsImpl;
65 import org.opendaylight.openflowplugin.impl.statistics.services.GetAllQueuesStatisticsFromAllPortsImpl;
66 import org.opendaylight.openflowplugin.impl.statistics.services.GetAllQueuesStatisticsFromGivenPortImpl;
67 import org.opendaylight.openflowplugin.impl.statistics.services.GetFlowTablesStatisticsImpl;
68 import org.opendaylight.openflowplugin.impl.statistics.services.GetGroupDescriptionImpl;
69 import org.opendaylight.openflowplugin.impl.statistics.services.GetGroupFeaturesImpl;
70 import org.opendaylight.openflowplugin.impl.statistics.services.GetGroupStatisticsImpl;
71 import org.opendaylight.openflowplugin.impl.statistics.services.GetMeterFeaturesImpl;
72 import org.opendaylight.openflowplugin.impl.statistics.services.GetMeterStatisticsImpl;
73 import org.opendaylight.openflowplugin.impl.statistics.services.GetNodeConnectorStatisticsImpl;
74 import org.opendaylight.openflowplugin.impl.statistics.services.GetQueueStatisticsFromGivenPortImpl;
75 import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.GetAggregateFlowStatisticsFromFlowTableForAllFlowsImpl;
76 import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.GetAllFlowStatisticsFromFlowTableImpl;
77 import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.GetAllFlowsStatisticsFromAllFlowTablesImpl;
78 import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.GetFlowStatisticsFromFlowTableImpl;
79 import org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer.MultiGetFlowStatistics;
80 import org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer.MultiGetGroupStatistics;
81 import org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer.MultiGetMeterStatistics;
82 import org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer.MultiGetNodeConnectorStatistics;
83 import org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer.MultiGetQueueStatistics;
84 import org.opendaylight.openflowplugin.impl.statistics.services.direct.singlelayer.SingleGetFlowStatistics;
85 import org.opendaylight.openflowplugin.impl.statistics.services.direct.singlelayer.SingleGetGroupStatistics;
86 import org.opendaylight.openflowplugin.impl.statistics.services.direct.singlelayer.SingleGetMeterStatistics;
87 import org.opendaylight.openflowplugin.impl.statistics.services.direct.singlelayer.SingleGetNodeConnectorStatistics;
88 import org.opendaylight.openflowplugin.impl.statistics.services.direct.singlelayer.SingleGetQueueStatistics;
89 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.async.config.service.rev170619.GetAsync;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.async.config.service.rev170619.SetAsync;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatistics;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatistics;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatistics;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatistics;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatistics;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.echo.service.rev150305.SendEcho;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.message.service.rev151020.SendExperimenter;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequest;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatch;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlow;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlow;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlow;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlows;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatch;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTable;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTables;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTable;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatistics;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.SendBarrier;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroup;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroup;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroup;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatistics;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescription;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeatures;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeter;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeter;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeter;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatistics;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeatures;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.module.config.rev141015.SetConfig;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.AddBundleMessages;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.ControlBundle;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacket;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePort;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatistics;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPorts;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromGivenPort;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPort;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTable;
134 import org.opendaylight.yangtools.concepts.Registration;
135 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
136 import org.opendaylight.yangtools.yang.binding.Rpc;
137 import org.slf4j.Logger;
138 import org.slf4j.LoggerFactory;
139
140 final class RpcContextImpl implements RpcContext {
141     private static final Logger LOG = LoggerFactory.getLogger(RpcContextImpl.class);
142
143     private final RpcProviderService rpcProviderRegistry;
144     private final MessageSpy messageSpy;
145     private final Semaphore tracker;
146     private final boolean isStatisticsRpcEnabled;
147     private final KeyedInstanceIdentifier<Node, NodeKey> nodeInstanceIdentifier;
148     private final DeviceInfo deviceInfo;
149     private final DeviceContext deviceContext;
150     private final ExtensionConverterProvider extensionConverterProvider;
151     private final ConvertorExecutor convertorExecutor;
152     private final NotificationPublishService notificationPublishService;
153
154     private ContextChainMastershipWatcher contextChainMastershipWatcher = null;
155     private Registration rpcRegistration;
156
157     RpcContextImpl(@NonNull final RpcProviderService rpcProviderRegistry,
158                    final int maxRequests,
159                    @NonNull final DeviceContext deviceContext,
160                    @NonNull final ExtensionConverterProvider extensionConverterProvider,
161                    @NonNull final ConvertorExecutor convertorExecutor,
162                    @NonNull final NotificationPublishService notificationPublishService,
163                    final boolean statisticsRpcEnabled) {
164         this.deviceContext = deviceContext;
165         deviceInfo = deviceContext.getDeviceInfo();
166         nodeInstanceIdentifier = deviceContext.getDeviceInfo().getNodeInstanceIdentifier();
167         messageSpy = deviceContext.getMessageSpy();
168         this.rpcProviderRegistry = rpcProviderRegistry;
169         this.extensionConverterProvider = extensionConverterProvider;
170         this.notificationPublishService = notificationPublishService;
171         this.convertorExecutor = convertorExecutor;
172         isStatisticsRpcEnabled = statisticsRpcEnabled;
173         tracker = new Semaphore(maxRequests, true);
174     }
175
176     @Override
177     public ServiceGroupIdentifier getIdentifier() {
178         return deviceInfo.getServiceIdentifier();
179     }
180
181     @Override
182     public void close() {
183         unregisterRPCs();
184     }
185
186     private void unregisterRPCs() {
187         if (rpcRegistration != null) {
188             LOG.debug("Closing RPC registrations for device {}.", nodeInstanceIdentifier.getKey().getId().getValue());
189             rpcRegistration.close();
190             rpcRegistration = null;
191         }
192     }
193
194     @Override
195     public <T> RequestContext<T> createRequestContext() {
196         if (!tracker.tryAcquire()) {
197             LOG.trace("Device queue {} at capacity", this);
198             return null;
199         }
200
201         LOG.trace("Acquired semaphore for {}, available permits:{} ",
202             nodeInstanceIdentifier.getKey().getId().getValue(), tracker.availablePermits());
203
204         final var xid = deviceInfo.reserveXidForDeviceMessage();
205         if (xid == null) {
206             LOG.warn("Xid cannot be reserved for new RequestContext, node:{}",
207                     nodeInstanceIdentifier.getKey().getId().getValue());
208             tracker.release();
209             return null;
210         }
211
212         return new AbstractRequestContext<>(xid) {
213             @Override
214             public void close() {
215                 tracker.release();
216                 LOG.trace("Removed request context with xid {}", getXid().getValue());
217                 messageSpy.spyMessage(RpcContextImpl.class, MessageSpy.StatisticsGroup.REQUEST_STACK_FREED);
218             }
219         };
220     }
221
222     @Override
223     public DeviceInfo getDeviceInfo() {
224         return deviceInfo;
225     }
226
227     @Override
228     public void registerMastershipWatcher(final ContextChainMastershipWatcher newWatcher) {
229         contextChainMastershipWatcher = newWatcher;
230     }
231
232     @Override
233     public ListenableFuture<?> closeServiceInstance() {
234         unregisterRPCs();
235         return Futures.immediateVoidFuture();
236     }
237
238     @Override
239     public void instantiateServiceInstance() {
240         // flow-capable-transaction.yang
241         final var sendBarrier = new SendBarrierImpl(this, deviceContext);
242
243         // sal-experimenter-message.yang
244         final var sendExperimenter = new SendExperimenterImpl(this, deviceContext, extensionConverterProvider);
245
246         // sal-flow.yang
247         final var addFlow = new AddFlowImpl(this, deviceContext, convertorExecutor);
248         final var removeFlow = new RemoveFlowImpl(this, deviceContext, convertorExecutor);
249         final var updateFlow = new UpdateFlowImpl(this, deviceContext, convertorExecutor);
250
251         // sal-group.yang
252         final var addGroup = new AddGroupImpl(this, deviceContext, convertorExecutor);
253         final var removeGroup = new RemoveGroupImpl(this, deviceContext, convertorExecutor);
254         final var updateGroup = new UpdateGroupImpl(this, deviceContext, convertorExecutor);
255
256         // sal-meter.yang
257         final var addMeter = new AddMeterImpl(this, deviceContext, convertorExecutor);
258         final var removeMeter = new RemoveMeterImpl(this, deviceContext, convertorExecutor);
259         final var updateMeter = new UpdateMeterImpl(this, deviceContext, convertorExecutor);
260
261         // FIXME: Use multipart writer provider from device context
262         final var multipartWriterProvider = MultipartWriterProviderFactory.createDefaultProvider(deviceContext);
263
264         final var singleLayer = deviceContext.canUseSingleLayerSerialization();
265
266         final var builder = ImmutableClassToInstanceMap.<Rpc<?, ?>>builder()
267             .put(SendBarrier.class, sendBarrier)
268             // node-config.yang
269             .put(SetConfig.class, new SetConfigImpl(this, deviceContext))
270             // packet-processing.yang
271             .put(TransmitPacket.class, new TransmitPacketImpl(this, deviceContext, convertorExecutor))
272             // sal-async-config.yang
273             .put(GetAsync.class, new GetAsyncImpl(this, deviceContext))
274             .put(SetAsync.class, new SetAsyncImpl(this, deviceContext))
275             // sal-echo.yang
276             .put(SendEcho.class, new SendEchoImpl(this, deviceContext))
277             .put(SendExperimenter.class, sendExperimenter)
278             // sal-bundle.yang (ONF extension?)
279             .put(ControlBundle.class, new ControlBundleImpl(sendExperimenter))
280             .put(AddBundleMessages.class, new AddBundleMessagesImpl(sendExperimenter))
281             // sal-experimenter-mp-message.yang
282             .put(SendExperimenterMpRequest.class, new SendExperimenterMpRequestImpl(this, deviceContext,
283                 extensionConverterProvider))
284             .put(AddFlow.class, addFlow)
285             .put(RemoveFlow.class, removeFlow)
286             .put(UpdateFlow.class, updateFlow)
287             .put(AddGroup.class, addGroup)
288             .put(RemoveGroup.class, removeGroup)
289             .put(UpdateGroup.class, updateGroup)
290             .put(AddMeter.class, addMeter)
291             .put(RemoveMeter.class, removeMeter)
292             .put(UpdateMeter.class, updateMeter)
293             // sal-port.yang
294             .put(UpdatePort.class, new UpdatePortImpl(this, deviceContext, convertorExecutor))
295             // sal-flat-batch.yang
296             .put(ProcessFlatBatch.class, new ProcessFlatBatchImpl(
297                 // sal-flows-batch.yang
298                 // FIXME: register these?
299                 new AddFlowsBatchImpl(addFlow, sendBarrier),
300                 new RemoveFlowsBatchImpl(removeFlow, sendBarrier),
301                 new UpdateFlowsBatchImpl(updateFlow, sendBarrier),
302                 // sal-groups-batch.yang
303                 // FIXME: register these?
304                 new AddGroupsBatchImpl(addGroup, sendBarrier),
305                 new RemoveGroupsBatchImpl(removeGroup, sendBarrier),
306                 new UpdateGroupsBatchImpl(updateGroup, sendBarrier),
307                 // sal-meters-batch.yang
308                 // FIXME: register these?
309                 new AddMetersBatchImpl(addMeter, sendBarrier),
310                 new RemoveMetersBatchImpl(removeMeter, sendBarrier),
311                 new UpdateMetersBatchImpl(updateMeter, sendBarrier)))
312             // sal-table.yang
313             .put(UpdateTable.class, new UpdateTableImpl(this, deviceContext, convertorExecutor,
314                 multipartWriterProvider))
315             // opendaylight-flow-statistics.yang
316             .put(GetAggregateFlowStatisticsFromFlowTableForGivenMatch.class,
317                 new GetAggregateFlowStatisticsFromFlowTableForGivenMatchImpl(this, deviceContext, convertorExecutor))
318             // opendaylight-direct-statistics.yang
319             .put(GetFlowStatistics.class, singleLayer
320                 ? new SingleGetFlowStatistics(this, deviceContext, convertorExecutor, multipartWriterProvider)
321                 : new MultiGetFlowStatistics(this, deviceContext, convertorExecutor, multipartWriterProvider))
322             .put(GetGroupStatistics.class, singleLayer
323                 ? new SingleGetGroupStatistics(this, deviceContext, convertorExecutor, multipartWriterProvider)
324                 : new MultiGetGroupStatistics(this, deviceContext, convertorExecutor, multipartWriterProvider))
325             .put(GetQueueStatistics.class, singleLayer
326                 ? new SingleGetQueueStatistics(this, deviceContext, convertorExecutor, multipartWriterProvider)
327                 : new MultiGetQueueStatistics(this, deviceContext, convertorExecutor, multipartWriterProvider))
328             .put(GetMeterStatistics.class, singleLayer
329                 ? new SingleGetMeterStatistics(this, deviceContext, convertorExecutor, multipartWriterProvider)
330                 : new MultiGetMeterStatistics(this, deviceContext, convertorExecutor, multipartWriterProvider))
331             .put(GetNodeConnectorStatistics.class, singleLayer
332                 ? new SingleGetNodeConnectorStatistics(this, deviceContext, convertorExecutor, multipartWriterProvider)
333                 : new MultiGetNodeConnectorStatistics(this, deviceContext, convertorExecutor, multipartWriterProvider));
334
335         // Support deprecated statistic related services for backward compatibility. The only exception from deprecation
336         // is the aggregated flow statistic with match criteria input.
337         if (isStatisticsRpcEnabled && !singleLayer) {
338             final var compatibilityXidSeed = new AtomicLong();
339             // FIXME: why is this separate?
340             final var statsCompatXidSeed = new AtomicLong();
341
342             builder
343                 // Legacy RPCs
344                 .put(GetAggregateFlowStatisticsFromFlowTableForAllFlows.class,
345                     new GetAggregateFlowStatisticsFromFlowTableForAllFlowsImpl(this, deviceContext, convertorExecutor,
346                         statsCompatXidSeed, notificationPublishService))
347                 .put(GetAllFlowStatisticsFromFlowTable.class,
348                     new GetAllFlowStatisticsFromFlowTableImpl(this, deviceContext, convertorExecutor,
349                         statsCompatXidSeed, notificationPublishService))
350                 .put(GetAllFlowsStatisticsFromAllFlowTables.class,
351                     new GetAllFlowsStatisticsFromAllFlowTablesImpl(this, deviceContext, convertorExecutor,
352                         statsCompatXidSeed, notificationPublishService))
353                 .put(GetFlowStatisticsFromFlowTable.class,
354                     new GetFlowStatisticsFromFlowTableImpl(this, deviceContext, convertorExecutor, statsCompatXidSeed,
355                         notificationPublishService))
356
357                 // register all statistics (deprecated) services
358                 .put(GetFlowTablesStatistics.class,
359                     new GetFlowTablesStatisticsImpl(this, deviceContext, compatibilityXidSeed,
360                         notificationPublishService))
361                 .put(org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupStatistics.class,
362                     new GetGroupStatisticsImpl(this, deviceContext, compatibilityXidSeed, notificationPublishService,
363                         convertorExecutor))
364                 .put(GetAllGroupStatistics.class,
365                     new GetAllGroupStatisticsImpl(this, deviceContext, compatibilityXidSeed, notificationPublishService,
366                         convertorExecutor))
367                 .put(GetGroupDescription.class,
368                     new GetGroupDescriptionImpl(this, deviceContext, compatibilityXidSeed, notificationPublishService,
369                         convertorExecutor))
370                 .put(GetGroupFeatures.class,
371                     new GetGroupFeaturesImpl(this, deviceContext, compatibilityXidSeed, notificationPublishService,
372                         convertorExecutor))
373                 .put(org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatistics.class,
374                     new GetMeterStatisticsImpl(this, deviceContext, compatibilityXidSeed, notificationPublishService,
375                         convertorExecutor))
376                 .put(org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111
377                         .GetAllMeterStatistics.class,
378                     new GetAllMeterStatisticsImpl(this, deviceContext, compatibilityXidSeed, notificationPublishService,
379                         convertorExecutor))
380                 .put(GetAllMeterConfigStatistics.class,
381                     new GetAllMeterConfigStatisticsImpl(this, deviceContext, compatibilityXidSeed,
382                         notificationPublishService, convertorExecutor))
383                 .put(GetMeterFeatures.class,
384                     new GetMeterFeaturesImpl(this, deviceContext, compatibilityXidSeed, notificationPublishService,
385                         convertorExecutor))
386                 .put(GetQueueStatisticsFromGivenPort.class,
387                     new GetQueueStatisticsFromGivenPortImpl(this, deviceContext, compatibilityXidSeed,
388                         notificationPublishService))
389                 .put(GetAllQueuesStatisticsFromAllPorts.class,
390                     new GetAllQueuesStatisticsFromAllPortsImpl(this, deviceContext, compatibilityXidSeed,
391                         notificationPublishService))
392                 .put(GetAllQueuesStatisticsFromGivenPort.class,
393                     new GetAllQueuesStatisticsFromGivenPortImpl(this, deviceContext, compatibilityXidSeed,
394                         notificationPublishService))
395                 .put(org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214
396                     .GetNodeConnectorStatistics.class,
397                     new GetNodeConnectorStatisticsImpl(this, deviceContext, compatibilityXidSeed,
398                         notificationPublishService))
399                 .put(GetAllNodeConnectorsStatistics.class,
400                     new GetAllNodeConnectorsStatisticsImpl(this, deviceContext, compatibilityXidSeed,
401                         notificationPublishService));
402         }
403
404         rpcRegistration = rpcProviderRegistry.registerRpcImplementations(builder.build(),
405             Set.of(nodeInstanceIdentifier));
406
407         final var local = contextChainMastershipWatcher;
408         if (local != null) {
409             local.onMasterRoleAcquired(deviceInfo, ContextChainMastershipState.RPC_REGISTRATION);
410         }
411     }
412 }