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 static java.util.Objects.requireNonNull;
12 import com.google.common.collect.ArrayListMultimap;
13 import com.google.common.collect.Iterables;
14 import com.google.common.collect.Multimap;
15 import com.google.common.collect.Multimaps;
16 import javax.annotation.PreDestroy;
17 import javax.inject.Inject;
18 import javax.inject.Singleton;
19 import org.apache.aries.blueprint.annotation.service.Reference;
20 import org.opendaylight.genius.fcapsapp.FcapsConstants;
21 import org.opendaylight.genius.fcapsapp.portinfo.PortNameMapping;
22 import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils;
23 import org.opendaylight.infrautils.metrics.Counter;
24 import org.opendaylight.infrautils.metrics.Labeled;
25 import org.opendaylight.infrautils.metrics.MetricDescriptor;
26 import org.opendaylight.infrautils.metrics.MetricProvider;
27 import org.opendaylight.mdsal.binding.api.DataBroker;
28 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
29 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
30 import org.opendaylight.openflowplugin.common.wait.SimpleTaskRetryLooper;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
35 import org.opendaylight.yangtools.concepts.ListenerRegistration;
36 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
41 public class FlowNodeConnectorInventoryTranslatorImpl extends NodeConnectorEventListener<FlowCapableNodeConnector> {
42 private static final Logger LOG = LoggerFactory.getLogger(FlowNodeConnectorInventoryTranslatorImpl.class);
44 private static final int STARTUP_LOOP_TICK = 500;
45 private static final int STARTUP_LOOP_MAX_RETRIES = 8;
47 private final EntityOwnershipUtils entityOwnershipUtils;
48 private ListenerRegistration<FlowNodeConnectorInventoryTranslatorImpl> dataTreeChangeListenerRegistration;
50 private static final String SEPARATOR = ":";
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(@Reference final DataBroker dataBroker,
64 final EntityOwnershipUtils entityOwnershipUtils,
65 @Reference MetricProvider metricProvider) {
66 requireNonNull(dataBroker, "DataBroker can not be null!");
67 this.entityOwnershipUtils = entityOwnershipUtils;
68 packetInCounter = metricProvider.newCounter(MetricDescriptor.builder().anchor(this)
69 .project("genius").module("fcapsapplication")
70 .id("entitycounter").build(), "entitytype", "switchid","name");
71 final DataTreeIdentifier<FlowCapableNodeConnector> treeId = DataTreeIdentifier.create(
72 LogicalDatastoreType.OPERATIONAL, getWildCardPath());
74 SimpleTaskRetryLooper looper = new SimpleTaskRetryLooper(STARTUP_LOOP_TICK, STARTUP_LOOP_MAX_RETRIES);
75 dataTreeChangeListenerRegistration = looper.loopUntilNoException(() -> dataBroker
76 .registerDataTreeChangeListener(treeId, FlowNodeConnectorInventoryTranslatorImpl.this));
77 } catch (Exception e) {
78 LOG.warn(" FlowNodeConnectorInventoryTranslatorImpl listener registration fail!");
79 LOG.debug("FlowNodeConnectorInventoryTranslatorImpl DataChange listener registration fail ..", e);
80 throw new IllegalStateException(
81 "FlowNodeConnectorInventoryTranslatorImpl startup fail! System needs restart.", e);
85 protected InstanceIdentifier<FlowCapableNodeConnector> getWildCardPath() {
86 return InstanceIdentifier.create(Nodes.class).child(Node.class).child(NodeConnector.class)
87 .augmentation(FlowCapableNodeConnector.class);
93 if (dataTreeChangeListenerRegistration != null) {
94 dataTreeChangeListenerRegistration.close();
95 dataTreeChangeListenerRegistration = null;
100 public void remove(InstanceIdentifier<FlowCapableNodeConnector> identifier, FlowCapableNodeConnector del,
101 InstanceIdentifier<FlowCapableNodeConnector> nodeConnIdent) {
103 if (compareInstanceIdentifierTail(identifier, II_TO_FLOW_CAPABLE_NODE_CONNECTOR)) {
104 String nodeConnectorIdentifier = getNodeConnectorId(
105 String.valueOf(nodeConnIdent.firstKeyOf(NodeConnector.class).getId()));
106 long dataPathId = getDpIdFromPortName(nodeConnectorIdentifier);
107 if (dpnToPortMultiMap.containsKey(dataPathId)) {
108 LOG.debug("Node Connector {} removed", nodeConnectorIdentifier);
109 dpnToPortMultiMap.remove(dataPathId, nodeConnectorIdentifier);
110 counter = packetInCounter.label("OFSwitch").label(String.valueOf(dataPathId)).label("portsperswitch");
112 PortNameMapping.updatePortMap("openflow:" + dataPathId + ":" + del.getName(), nodeConnectorIdentifier,
119 public void update(InstanceIdentifier<FlowCapableNodeConnector> identifier, FlowCapableNodeConnector original,
120 FlowCapableNodeConnector update, InstanceIdentifier<FlowCapableNodeConnector> nodeConnIdent) {
121 // Don't need to do anything as we are not considering updates here
125 public void add(InstanceIdentifier<FlowCapableNodeConnector> identifier, FlowCapableNodeConnector add,
126 InstanceIdentifier<FlowCapableNodeConnector> nodeConnIdent) {
128 if (compareInstanceIdentifierTail(identifier, II_TO_FLOW_CAPABLE_NODE_CONNECTOR)) {
130 String nodeConnectorIdentifier = getNodeConnectorId(
131 String.valueOf(nodeConnIdent.firstKeyOf(NodeConnector.class).getId()));
132 long dataPathId = getDpIdFromPortName(nodeConnectorIdentifier);
133 if (entityOwnershipUtils.isEntityOwner(FcapsConstants.SERVICE_ENTITY_TYPE,getNodeId(dataPathId))) {
134 if (!dpnToPortMultiMap.containsEntry(dataPathId, nodeConnectorIdentifier)) {
135 LOG.debug("Node Connector {} added", nodeConnectorIdentifier);
136 dpnToPortMultiMap.put(dataPathId, nodeConnectorIdentifier);
137 counter = packetInCounter.label("OFSwitch")
138 .label(String.valueOf(dataPathId)).label("portsperswitch");
140 PortNameMapping.updatePortMap("openflow:" + dataPathId + ":" + add.getName(),
141 nodeConnectorIdentifier, "ADD");
143 LOG.error("Duplicate Event.Node Connector already added");
149 private String getNodeConnectorId(String node) {
150 // Uri [_value=openflow:1:1]
151 String[] temp = node.split("=");
152 return temp[1].substring(0, temp[1].length() - 1);
155 private String getNodeId(Long dpnId) {
156 return "openflow:" + dpnId;
159 private boolean compareInstanceIdentifierTail(InstanceIdentifier<?> identifier1,
160 InstanceIdentifier<?> identifier2) {
161 return Iterables.getLast(identifier1.getPathArguments())
162 .equals(Iterables.getLast(identifier2.getPathArguments()));
165 private long getDpIdFromPortName(String portName) {
166 String dpId = portName.substring(portName.indexOf(SEPARATOR) + 1, portName.lastIndexOf(SEPARATOR));
167 return Long.parseLong(dpId);
170 public void nodeRemovedNotification(String node) {
172 String[] switchId = node.split(":");
173 counter = packetInCounter.label("OFSwitch").label(String.valueOf(switchId[1])).label("portsperswitch");