2 * Copyright (c) 2016, 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
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
8 package org.opendaylight.genius.fcapsapp.performancecounter;
10 import com.google.common.base.Preconditions;
11 import com.google.common.collect.ArrayListMultimap;
12 import com.google.common.collect.Iterables;
13 import com.google.common.collect.Multimap;
14 import com.google.common.collect.Multimaps;
15 import javax.annotation.PreDestroy;
16 import javax.inject.Inject;
17 import javax.inject.Singleton;
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
21 import org.opendaylight.genius.fcapsapp.FcapsConstants;
22 import org.opendaylight.genius.fcapsapp.portinfo.PortNameMapping;
23 import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils;
24 import org.opendaylight.infrautils.metrics.Counter;
25 import org.opendaylight.infrautils.metrics.Labeled;
26 import org.opendaylight.infrautils.metrics.MetricDescriptor;
27 import org.opendaylight.infrautils.metrics.MetricProvider;
28 import org.opendaylight.openflowplugin.common.wait.SimpleTaskRetryLooper;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
33 import org.opendaylight.yangtools.concepts.ListenerRegistration;
34 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
39 public class FlowNodeConnectorInventoryTranslatorImpl extends NodeConnectorEventListener<FlowCapableNodeConnector> {
40 private static final Logger LOG = LoggerFactory.getLogger(FlowNodeConnectorInventoryTranslatorImpl.class);
42 private static final int STARTUP_LOOP_TICK = 500;
43 private static final int STARTUP_LOOP_MAX_RETRIES = 8;
45 private final EntityOwnershipUtils entityOwnershipUtils;
46 private final DataBroker dataBroker;
47 private ListenerRegistration<FlowNodeConnectorInventoryTranslatorImpl> dataTreeChangeListenerRegistration;
49 private static final String SEPARATOR = ":";
50 private final MetricProvider metricProvider;
51 private final Labeled<Labeled<Labeled<Counter>>> packetInCounter;
52 private static final InstanceIdentifier<FlowCapableNodeConnector>
53 II_TO_FLOW_CAPABLE_NODE_CONNECTOR = InstanceIdentifier
54 .builder(Nodes.class).child(Node.class).child(NodeConnector.class)
55 .augmentation(FlowCapableNodeConnector.class).build();
57 private static Multimap<Long, String> dpnToPortMultiMap = Multimaps
58 .synchronizedListMultimap(ArrayListMultimap.<Long, String>create());
62 @SuppressWarnings("checkstyle:IllegalCatch")
63 public FlowNodeConnectorInventoryTranslatorImpl(final DataBroker dataBroker,
64 final EntityOwnershipUtils entityOwnershipUtils,
65 MetricProvider metricProvider) {
66 this.dataBroker = Preconditions.checkNotNull(dataBroker, "DataBroker can not be null!");
67 this.entityOwnershipUtils = entityOwnershipUtils;
68 this.metricProvider = metricProvider;
69 packetInCounter = metricProvider.newCounter(MetricDescriptor.builder().anchor(this)
70 .project("genius").module("fcapsapplication")
71 .id("entitycounter").build(), "entitytype", "switchid","name");
72 final DataTreeIdentifier<FlowCapableNodeConnector> treeId = new DataTreeIdentifier<>(
73 LogicalDatastoreType.OPERATIONAL, getWildCardPath());
75 SimpleTaskRetryLooper looper = new SimpleTaskRetryLooper(STARTUP_LOOP_TICK, STARTUP_LOOP_MAX_RETRIES);
76 dataTreeChangeListenerRegistration = looper.loopUntilNoException(() -> dataBroker
77 .registerDataTreeChangeListener(treeId, FlowNodeConnectorInventoryTranslatorImpl.this));
78 } catch (Exception e) {
79 LOG.warn(" FlowNodeConnectorInventoryTranslatorImpl listener registration fail!");
80 LOG.debug("FlowNodeConnectorInventoryTranslatorImpl DataChange listener registration fail ..", e);
81 throw new IllegalStateException(
82 "FlowNodeConnectorInventoryTranslatorImpl startup fail! System needs restart.", e);
86 protected InstanceIdentifier<FlowCapableNodeConnector> getWildCardPath() {
87 return InstanceIdentifier.create(Nodes.class).child(Node.class).child(NodeConnector.class)
88 .augmentation(FlowCapableNodeConnector.class);
94 if (dataTreeChangeListenerRegistration != null) {
95 dataTreeChangeListenerRegistration.close();
96 dataTreeChangeListenerRegistration = null;
101 public void remove(InstanceIdentifier<FlowCapableNodeConnector> identifier, FlowCapableNodeConnector del,
102 InstanceIdentifier<FlowCapableNodeConnector> nodeConnIdent) {
104 if (compareInstanceIdentifierTail(identifier, II_TO_FLOW_CAPABLE_NODE_CONNECTOR)) {
105 String nodeConnectorIdentifier = getNodeConnectorId(
106 String.valueOf(nodeConnIdent.firstKeyOf(NodeConnector.class).getId()));
107 long dataPathId = getDpIdFromPortName(nodeConnectorIdentifier);
108 if (dpnToPortMultiMap.containsKey(dataPathId)) {
109 LOG.debug("Node Connector {} removed", nodeConnectorIdentifier);
110 dpnToPortMultiMap.remove(dataPathId, nodeConnectorIdentifier);
111 counter = packetInCounter.label("OFSwitch").label(String.valueOf(dataPathId)).label("portsperswitch");
113 PortNameMapping.updatePortMap("openflow:" + dataPathId + ":" + del.getName(), nodeConnectorIdentifier,
120 public void update(InstanceIdentifier<FlowCapableNodeConnector> identifier, FlowCapableNodeConnector original,
121 FlowCapableNodeConnector update, InstanceIdentifier<FlowCapableNodeConnector> nodeConnIdent) {
122 // Don't need to do anything as we are not considering updates here
126 public void add(InstanceIdentifier<FlowCapableNodeConnector> identifier, FlowCapableNodeConnector add,
127 InstanceIdentifier<FlowCapableNodeConnector> nodeConnIdent) {
129 if (compareInstanceIdentifierTail(identifier, II_TO_FLOW_CAPABLE_NODE_CONNECTOR)) {
131 String nodeConnectorIdentifier = getNodeConnectorId(
132 String.valueOf(nodeConnIdent.firstKeyOf(NodeConnector.class).getId()));
133 long dataPathId = getDpIdFromPortName(nodeConnectorIdentifier);
134 if (entityOwnershipUtils.isEntityOwner(FcapsConstants.SERVICE_ENTITY_TYPE,getNodeId(dataPathId))) {
135 if (!dpnToPortMultiMap.containsEntry(dataPathId, nodeConnectorIdentifier)) {
136 LOG.debug("Node Connector {} added", nodeConnectorIdentifier);
137 dpnToPortMultiMap.put(dataPathId, nodeConnectorIdentifier);
138 counter = packetInCounter.label("OFSwitch")
139 .label(String.valueOf(dataPathId)).label("portsperswitch");
141 PortNameMapping.updatePortMap("openflow:" + dataPathId + ":" + add.getName(),
142 nodeConnectorIdentifier, "ADD");
144 LOG.error("Duplicate Event.Node Connector already added");
150 private String getNodeConnectorId(String node) {
151 // Uri [_value=openflow:1:1]
152 String[] temp = node.split("=");
153 return temp[1].substring(0, temp[1].length() - 1);
156 private String getNodeId(Long dpnId) {
157 return "openflow:" + dpnId;
160 private boolean compareInstanceIdentifierTail(InstanceIdentifier<?> identifier1,
161 InstanceIdentifier<?> identifier2) {
162 return Iterables.getLast(identifier1.getPathArguments())
163 .equals(Iterables.getLast(identifier2.getPathArguments()));
166 private long getDpIdFromPortName(String portName) {
167 String dpId = portName.substring(portName.indexOf(SEPARATOR) + 1, portName.lastIndexOf(SEPARATOR));
168 return Long.parseLong(dpId);
171 public void nodeRemovedNotification(String node) {
173 String[] switchId = node.split(":");
174 counter = packetInCounter.label("OFSwitch").label(String.valueOf(switchId[1])).label("portsperswitch");