Bug 6193 - Change in length of DatapathId of a switch
[openflowplugin.git] / applications / forwardingrules-manager / src / main / java / org / opendaylight / openflowplugin / applications / frm / impl / FlowNodeConnectorInventoryTranslatorImpl.java
1 /**
2  * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.base.Preconditions;
12 import com.google.common.collect.*;
13 import org.opendaylight.controller.md.sal.binding.api.*;
14 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
15 import org.opendaylight.openflowplugin.applications.frm.FlowNodeConnectorInventoryTranslator;
16 import org.opendaylight.openflowplugin.applications.frm.ForwardingRulesManager;
17 import org.opendaylight.openflowplugin.common.wait.SimpleTaskRetryLooper;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
23 import org.opendaylight.yangtools.concepts.ListenerRegistration;
24 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 import java.math.BigInteger;
29 import java.util.concurrent.Callable;
30
31 public class FlowNodeConnectorInventoryTranslatorImpl extends AbstractNodeConnectorCommitter<FlowCapableNodeConnector> implements FlowNodeConnectorInventoryTranslator {
32
33     private static final Logger LOG = LoggerFactory.getLogger(FlowNodeConnectorInventoryTranslatorImpl.class);
34
35     private ListenerRegistration<FlowNodeConnectorInventoryTranslatorImpl> dataTreeChangeListenerRegistration;
36
37     public static final String SEPARATOR = ":";
38
39     private static final InstanceIdentifier<FlowCapableNodeConnector> II_TO_FLOW_CAPABLE_NODE_CONNECTOR
40             = InstanceIdentifier.builder(Nodes.class)
41             .child(Node.class)
42             .child(NodeConnector.class)
43             .augmentation(FlowCapableNodeConnector.class)
44             .build();
45
46     private Multimap<BigInteger,String> dpnToPortMultiMap = Multimaps.synchronizedListMultimap(ArrayListMultimap.<BigInteger,String>create());
47
48     public FlowNodeConnectorInventoryTranslatorImpl(final ForwardingRulesManager manager, final DataBroker dataBroker){
49         super(manager, FlowCapableNodeConnector.class);
50         Preconditions.checkNotNull(dataBroker, "DataBroker can not be null!");
51
52         final DataTreeIdentifier<FlowCapableNodeConnector> treeId =
53                 new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, getWildCardPath());
54         try {
55             SimpleTaskRetryLooper looper = new SimpleTaskRetryLooper(ForwardingRulesManagerImpl.STARTUP_LOOP_TICK,
56                     ForwardingRulesManagerImpl.STARTUP_LOOP_MAX_RETRIES);
57             dataTreeChangeListenerRegistration = looper.loopUntilNoException(new Callable<ListenerRegistration<FlowNodeConnectorInventoryTranslatorImpl>>() {
58                 @Override
59                 public ListenerRegistration<FlowNodeConnectorInventoryTranslatorImpl> call() throws Exception {
60                     return dataBroker.registerDataTreeChangeListener(treeId, FlowNodeConnectorInventoryTranslatorImpl.this);
61                 }
62             });
63         } catch (final Exception e) {
64             LOG.warn(" FlowNodeConnectorInventoryTranslatorImpl listener registration fail!");
65             LOG.debug("FlowNodeConnectorInventoryTranslatorImpl DataChange listener registration fail ..", e);
66             throw new IllegalStateException("FlowNodeConnectorInventoryTranslatorImpl startup fail! System needs restart.", e);
67         }
68     }
69
70     @Override
71     protected InstanceIdentifier<FlowCapableNodeConnector> getWildCardPath(){
72         return InstanceIdentifier.create(Nodes.class)
73                 .child(Node.class)
74                 .child(NodeConnector.class)
75                 .augmentation(FlowCapableNodeConnector.class);
76     }
77
78     @Override
79     public void close() {
80         if (dataTreeChangeListenerRegistration != null) {
81             try {
82                 dataTreeChangeListenerRegistration.close();
83             } catch (final Exception e) {
84                 LOG.warn("Error by stop FRM FlowNodeConnectorInventoryTranslatorImpl: {}", e.getMessage());
85                 LOG.debug("Error by stop FRM FlowNodeConnectorInventoryTranslatorImpl..", e);
86             }
87             dataTreeChangeListenerRegistration = null;
88         }
89     }
90     @Override
91     public void remove(InstanceIdentifier<FlowCapableNodeConnector> identifier, FlowCapableNodeConnector del, InstanceIdentifier<FlowCapableNodeConnector> nodeConnIdent) {
92         if(compareInstanceIdentifierTail(identifier,II_TO_FLOW_CAPABLE_NODE_CONNECTOR)){
93             LOG.info("Node Connector removed");
94             String sNodeConnectorIdentifier = nodeConnIdent
95                     .firstKeyOf(NodeConnector.class, NodeConnectorKey.class).getId().getValue();
96             BigInteger nDpId = getDpIdFromPortName(sNodeConnectorIdentifier);
97             String portName = del.getName();
98
99             dpnToPortMultiMap.remove(nDpId, sNodeConnectorIdentifier);
100         }
101     }
102
103     @Override
104     public void update(InstanceIdentifier<FlowCapableNodeConnector> identifier, FlowCapableNodeConnector original, FlowCapableNodeConnector update, InstanceIdentifier<FlowCapableNodeConnector> nodeConnIdent) {
105         if(compareInstanceIdentifierTail(identifier,II_TO_FLOW_CAPABLE_NODE_CONNECTOR)){
106             LOG.info("Node Connector updated");
107             //donot need to do anything as we are not considering updates here
108         }
109     }
110
111     @Override
112     public void add(InstanceIdentifier<FlowCapableNodeConnector> identifier, FlowCapableNodeConnector add, InstanceIdentifier<FlowCapableNodeConnector> nodeConnIdent) {
113         if(compareInstanceIdentifierTail(identifier,II_TO_FLOW_CAPABLE_NODE_CONNECTOR)){
114             LOG.info("Node Connector added");
115             String sNodeConnectorIdentifier = nodeConnIdent
116                     .firstKeyOf(NodeConnector.class, NodeConnectorKey.class).getId().getValue();
117             BigInteger nDpId = getDpIdFromPortName(sNodeConnectorIdentifier);
118
119             String portName = add.getName();
120             if(!dpnToPortMultiMap.containsEntry(nDpId,sNodeConnectorIdentifier)) {
121                 dpnToPortMultiMap.put(nDpId, sNodeConnectorIdentifier);
122             }else{
123                 LOG.error("Duplicate Event.Node Connector already added");
124             }
125         }
126     }
127
128     private boolean compareInstanceIdentifierTail(InstanceIdentifier<?> identifier1,
129                                   InstanceIdentifier<?> identifier2) {
130         return Iterables.getLast(identifier1.getPathArguments()).equals(Iterables.getLast(identifier2.getPathArguments()));
131     }
132
133     @Override
134     public boolean isNodeConnectorUpdated(BigInteger dpId, String portName){
135         return dpnToPortMultiMap.containsEntry(dpId,portName) ;
136     }
137
138
139     private BigInteger getDpIdFromPortName(String portName) {
140         String dpId = portName.substring(portName.indexOf(SEPARATOR) + 1, portName.lastIndexOf(SEPARATOR));
141         return new BigInteger(dpId);
142     }
143 }
144