Merge "Removed duplicate declaration in pom.xml."
[openflowplugin.git] / applications / forwardingrules-manager / src / main / java / org / opendaylight / openflowplugin / applications / frm / impl / ForwardingRulesManagerImpl.java
1 /**
2  * Copyright (c) 2014, 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
9 package org.opendaylight.openflowplugin.applications.frm.impl;
10
11 import com.google.common.annotations.VisibleForTesting;
12 import com.google.common.base.Optional;
13 import com.google.common.base.Preconditions;
14 import com.google.common.collect.Sets;
15 import com.google.common.util.concurrent.CheckedFuture;
16 import java.util.Collections;
17 import java.util.Set;
18 import java.util.concurrent.atomic.AtomicLong;
19 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
23 import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
24 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
25 import org.opendaylight.openflowplugin.applications.frm.FlowNodeReconciliation;
26 import org.opendaylight.openflowplugin.applications.frm.ForwardingRulesCommiter;
27 import org.opendaylight.openflowplugin.applications.frm.ForwardingRulesManager;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.app.forwardingrules.manager.config.rev160511.ForwardingRulesManagerConfig;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.SalTableService;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures;
39 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 /**
44  * forwardingrules-manager
45  * org.opendaylight.openflowplugin.applications.frm.impl
46  *
47  * Manager and middle point for whole module.
48  * It contains ActiveNodeHolder and provide all RPC services.
49  *
50  */
51 public class ForwardingRulesManagerImpl implements ForwardingRulesManager {
52
53     private static final Logger LOG = LoggerFactory.getLogger(ForwardingRulesManagerImpl.class);
54     static final int STARTUP_LOOP_TICK = 500;
55     static final int STARTUP_LOOP_MAX_RETRIES = 8;
56
57     private final AtomicLong txNum = new AtomicLong();
58     private final Object lockObj = new Object();
59     private Set<InstanceIdentifier<FlowCapableNode>> activeNodes = Collections.emptySet();
60
61     private final DataBroker dataService;
62     private final SalFlowService salFlowService;
63     private final SalGroupService salGroupService;
64     private final SalMeterService salMeterService;
65     private final SalTableService salTableService;
66
67     private ForwardingRulesCommiter<Flow> flowListener;
68     private ForwardingRulesCommiter<Group> groupListener;
69     private ForwardingRulesCommiter<Meter> meterListener;
70     private ForwardingRulesCommiter<TableFeatures> tableListener;
71     private FlowNodeReconciliation nodeListener;
72
73     private final ForwardingRulesManagerConfig forwardingRulesManagerConfig;
74     private FlowNodeConnectorInventoryTranslatorImpl flowNodeConnectorInventoryTranslatorImpl;
75     private final ClusterSingletonServiceProvider clusterSingletonServiceProvider;
76     private DeviceMastershipManager deviceMastershipManager;
77
78     public ForwardingRulesManagerImpl(final DataBroker dataBroker,
79                                       final RpcConsumerRegistry rpcRegistry,
80                                       final ForwardingRulesManagerConfig config,
81                                       final ClusterSingletonServiceProvider clusterSingletonService) {
82         this.dataService = Preconditions.checkNotNull(dataBroker, "DataBroker can not be null!");
83         this.forwardingRulesManagerConfig = Preconditions.checkNotNull(config, "Configuration for FRM cannot be null");
84         this.clusterSingletonServiceProvider = Preconditions.checkNotNull(clusterSingletonService,
85                 "ClusterSingletonService provider can not be null");
86
87         Preconditions.checkArgument(rpcRegistry != null, "RpcConsumerRegistry can not be null !");
88
89         this.salFlowService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalFlowService.class),
90                 "RPC SalFlowService not found.");
91         this.salGroupService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalGroupService.class),
92                 "RPC SalGroupService not found.");
93         this.salMeterService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalMeterService.class),
94                 "RPC SalMeterService not found.");
95         this.salTableService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalTableService.class),
96                 "RPC SalTableService not found.");
97     }
98
99     @Override
100     public void start() {
101         this.flowListener = new FlowForwarder(this, dataService);
102         this.groupListener = new GroupForwarder(this, dataService);
103         this.meterListener = new MeterForwarder(this, dataService);
104         this.tableListener = new TableForwarder(this, dataService);
105         this.deviceMastershipManager = new DeviceMastershipManager(clusterSingletonServiceProvider);
106         this.nodeListener = new FlowNodeReconciliationImpl(this, dataService);
107         flowNodeConnectorInventoryTranslatorImpl =
108                 new FlowNodeConnectorInventoryTranslatorImpl(this,dataService);
109         LOG.info("ForwardingRulesManager has started successfully.");
110     }
111
112     @Override
113     public void close() throws Exception {
114         if (this.flowListener != null) {
115             this.flowListener.close();
116             this.flowListener = null;
117         }
118         if (this.groupListener != null) {
119             this.groupListener.close();
120             this.groupListener = null;
121         }
122         if (this.meterListener != null) {
123             this.meterListener.close();
124             this.meterListener = null;
125         }
126         if (this.tableListener != null) {
127             this.tableListener.close();
128             this.tableListener = null;
129         }
130         if (this.nodeListener != null) {
131             this.nodeListener.close();
132             this.nodeListener = null;
133         }
134     }
135
136     @Override
137     public ReadOnlyTransaction getReadTranaction() {
138         return dataService.newReadOnlyTransaction();
139     }
140
141     @Override
142     public String getNewTransactionId() {
143         return "DOM-" + txNum.getAndIncrement();
144     }
145
146     @Override
147     public boolean isNodeActive(InstanceIdentifier<FlowCapableNode> ident) {
148         return activeNodes.contains(ident);
149     }
150
151     @Override
152     public boolean checkNodeInOperationalDataStore(InstanceIdentifier<FlowCapableNode> ident) {
153         boolean result = false;
154         InstanceIdentifier<Node> nodeIid = ident.firstIdentifierOf(Node.class);
155         final ReadOnlyTransaction transaction = dataService.newReadOnlyTransaction();
156         Optional<Node> optionalDataObject;
157         CheckedFuture<Optional<Node>, ReadFailedException> future = transaction.read(LogicalDatastoreType.OPERATIONAL, nodeIid);
158         try {
159             optionalDataObject = future.checkedGet();
160             if (optionalDataObject.isPresent()) {
161                 result = true;
162             } else {
163                 LOG.debug("{}: Failed to read {}",
164                         Thread.currentThread().getStackTrace()[1], nodeIid);
165             }
166         } catch (ReadFailedException e) {
167             LOG.warn("Failed to read {} ", nodeIid, e);
168         }
169         transaction.close();
170
171         return result;
172     }
173
174     @Override
175     public void registrateNewNode(InstanceIdentifier<FlowCapableNode> ident) {
176         if (!activeNodes.contains(ident)) {
177             synchronized (lockObj) {
178                 if (!activeNodes.contains(ident)) {
179                     Set<InstanceIdentifier<FlowCapableNode>> set =
180                             Sets.newHashSet(activeNodes);
181                     set.add(ident);
182                     activeNodes = Collections.unmodifiableSet(set);
183                     deviceMastershipManager.onDeviceConnected(ident.firstKeyOf(Node.class).getId());
184                 }
185             }
186         }
187     }
188
189     @Override
190     public void unregistrateNode(InstanceIdentifier<FlowCapableNode> ident) {
191         if (activeNodes.contains(ident)) {
192             synchronized (lockObj) {
193                 if (activeNodes.contains(ident)) {
194                     Set<InstanceIdentifier<FlowCapableNode>> set =
195                             Sets.newHashSet(activeNodes);
196                     set.remove(ident);
197                     activeNodes = Collections.unmodifiableSet(set);
198                     deviceMastershipManager.onDeviceDisconnected(ident.firstKeyOf(Node.class).getId());
199                 }
200             }
201         }
202     }
203
204     @Override
205     public SalFlowService getSalFlowService() {
206         return salFlowService;
207     }
208
209     @Override
210     public SalGroupService getSalGroupService() {
211         return salGroupService;
212     }
213
214     @Override
215     public SalMeterService getSalMeterService() {
216         return salMeterService;
217     }
218
219     @Override
220     public SalTableService getSalTableService() {
221         return salTableService;
222     }
223
224     @Override
225     public ForwardingRulesCommiter<Flow> getFlowCommiter() {
226         return flowListener;
227     }
228
229     @Override
230     public ForwardingRulesCommiter<Group> getGroupCommiter() {
231         return groupListener;
232     }
233
234     @Override
235     public ForwardingRulesCommiter<Meter> getMeterCommiter() {
236         return meterListener;
237     }
238
239     @Override
240     public ForwardingRulesCommiter<TableFeatures> getTableFeaturesCommiter() {
241         return tableListener;
242     }
243
244     @Override
245     public FlowNodeReconciliation getFlowNodeReconciliation() {
246         return nodeListener;
247     }
248
249     @Override
250     public ForwardingRulesManagerConfig getConfiguration() {
251         return forwardingRulesManagerConfig;
252     }
253
254     @Override
255     public FlowNodeConnectorInventoryTranslatorImpl getFlowNodeConnectorInventoryTranslatorImpl() {
256         return flowNodeConnectorInventoryTranslatorImpl;
257     }
258
259     @Override
260     public boolean isNodeOwner(InstanceIdentifier<FlowCapableNode> ident) {
261         return deviceMastershipManager.isDeviceMastered(ident.firstKeyOf(Node.class).getId());
262     }
263
264     @VisibleForTesting
265     public void setDeviceMastershipManager(final DeviceMastershipManager deviceMastershipManager) {
266         this.deviceMastershipManager = deviceMastershipManager;
267     }
268
269 }
270