2 * Copyright (c) 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
9 package org.opendaylight.netvirt.qosservice;
11 import com.google.common.base.Optional;
12 import java.util.Collections;
13 import javax.annotation.PostConstruct;
14 import javax.inject.Inject;
15 import javax.inject.Singleton;
16 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
17 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
18 import org.opendaylight.genius.datastoreutils.AsyncClusteredDataTreeChangeListenerBase;
19 import org.opendaylight.genius.mdsalutil.NwConstants;
20 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
21 import org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager;
22 import org.opendaylight.netvirt.qosservice.recovery.QosServiceRecoveryHandler;
23 import org.opendaylight.serviceutils.srm.RecoverableListener;
24 import org.opendaylight.serviceutils.srm.ServiceRecoveryRegistry;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.L2vlan;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.qos.ext.rev160613.QosNetworkExtension;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.qos.ext.rev160613.QosPortExtension;
33 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
38 public class QosInterfaceStateChangeListener extends AsyncClusteredDataTreeChangeListenerBase<Interface,
39 QosInterfaceStateChangeListener> implements RecoverableListener {
41 private static final Logger LOG = LoggerFactory.getLogger(QosInterfaceStateChangeListener.class);
43 private final DataBroker dataBroker;
44 private final UuidUtil uuidUtil;
45 private final QosAlertManager qosAlertManager;
46 private final QosNeutronUtils qosNeutronUtils;
47 private final INeutronVpnManager neutronVpnManager;
48 private final JobCoordinator jobCoordinator;
51 public QosInterfaceStateChangeListener(final DataBroker dataBroker, final QosAlertManager qosAlertManager,
52 final QosNeutronUtils qosNeutronUtils,
53 final INeutronVpnManager neutronVpnManager,
54 final ServiceRecoveryRegistry serviceRecoveryRegistry,
55 final QosServiceRecoveryHandler qosServiceRecoveryHandler,
56 final JobCoordinator jobCoordinator) {
57 super(Interface.class, QosInterfaceStateChangeListener.class);
58 this.dataBroker = dataBroker;
59 this.uuidUtil = new UuidUtil();
60 this.qosAlertManager = qosAlertManager;
61 this.qosNeutronUtils = qosNeutronUtils;
62 this.neutronVpnManager = neutronVpnManager;
63 this.jobCoordinator = jobCoordinator;
64 serviceRecoveryRegistry.addRecoverableListener(qosServiceRecoveryHandler.buildServiceRegistryKey(),
66 LOG.trace("{} created", getClass().getSimpleName());
72 LOG.trace("{} init and registerListener done", getClass().getSimpleName());
76 public void registerListener() {
77 registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
81 protected InstanceIdentifier<Interface> getWildCardPath() {
82 return InstanceIdentifier.create(InterfacesState.class).child(Interface.class);
86 protected QosInterfaceStateChangeListener getDataTreeChangeListener() {
87 return QosInterfaceStateChangeListener.this;
91 @SuppressWarnings("checkstyle:IllegalCatch")
92 protected void add(InstanceIdentifier<Interface> identifier, Interface intrf) {
93 if (L2vlan.class.equals(intrf.getType())) {
94 final String interfaceName = intrf.getName();
95 getNeutronPort(interfaceName).ifPresent(port -> {
96 Network network = qosNeutronUtils.getNeutronNetwork(port.getNetworkId());
97 LOG.debug("Qos Service : Received interface {} PORT UP event ", interfaceName);
98 if (port.augmentation(QosPortExtension.class) != null) {
99 Uuid portQosUuid = port.augmentation(QosPortExtension.class).getQosPolicyId();
100 if (portQosUuid != null) {
101 qosNeutronUtils.addToQosPortsCache(portQosUuid, port);
102 qosNeutronUtils.handleQosInterfaceAdd(port, portQosUuid);
105 if (network.augmentation(QosNetworkExtension.class) != null) {
106 Uuid networkQosUuid = network.augmentation(QosNetworkExtension.class).getQosPolicyId();
107 if (networkQosUuid != null) {
108 qosNeutronUtils.handleQosInterfaceAdd(port, networkQosUuid);
112 qosAlertManager.processInterfaceUpEvent(interfaceName);
117 private java.util.Optional<Port> getNeutronPort(String portName) {
118 return uuidUtil.newUuidIfValidPattern(portName)
120 .map(qosNeutronUtils::getNeutronPort);
123 private Optional<Port> getNeutronPortForRemove(Interface intrf) {
124 final String portName = intrf.getName();
125 Optional<Uuid> uuid = uuidUtil.newUuidIfValidPattern(portName);
126 if (uuid.isPresent()) {
127 Port port = qosNeutronUtils.getNeutronPort(portName);
129 return Optional.fromJavaUtil(uuid.toJavaUtil().map(qosNeutronUtils::getNeutronPort));
131 if (qosNeutronUtils.isBindServiceDone(uuid)) {
132 LOG.trace("Qos Service : interface {} clearing stale flow entries if any", portName);
133 jobCoordinator.enqueueJob("QosPort-" + portName, () -> {
134 qosNeutronUtils.removeStaleFlowEntry(intrf, NwConstants.ETHTYPE_IPV4);
135 qosNeutronUtils.removeStaleFlowEntry(intrf, NwConstants.ETHTYPE_IPV6);
136 qosNeutronUtils.unbindservice(portName);
137 qosNeutronUtils.removeInterfaceInQosConfiguredPorts(uuid);
138 return Collections.emptyList();
142 return Optional.absent();
146 protected void remove(InstanceIdentifier<Interface> identifier, Interface intrf) {
147 if (L2vlan.class.equals(intrf.getType())) {
148 final String interfaceName = intrf.getName();
149 // Guava Optional asSet().forEach() emulates Java 8 Optional ifPresent()
150 getNeutronPortForRemove(intrf).asSet().forEach(port -> {
151 LOG.trace("Qos Service : Received interface {} PORT DOWN event ", interfaceName);
153 String lowerLayerIf = intrf.getLowerLayerIf().get(0);
154 LOG.trace("lowerLayerIf {}", lowerLayerIf);
155 qosAlertManager.removeLowerLayerIfFromQosAlertCache(lowerLayerIf);
156 QosPortExtension removeQos = port.augmentation(QosPortExtension.class);
157 if (removeQos != null) {
158 qosNeutronUtils.handleNeutronPortRemove(port, removeQos.getQosPolicyId(), intrf);
159 qosNeutronUtils.removeFromQosPortsCache(removeQos.getQosPolicyId(), port);
161 Network network = qosNeutronUtils.getNeutronNetwork(port.getNetworkId());
162 if (network != null && network.augmentation(QosNetworkExtension.class) != null) {
163 Uuid networkQosUuid = network.augmentation(QosNetworkExtension.class).getQosPolicyId();
164 if (networkQosUuid != null) {
165 qosNeutronUtils.handleNeutronPortRemove(port, networkQosUuid, intrf);
174 protected void update(InstanceIdentifier<Interface> identifier, Interface original, Interface update) {
175 if (original.getType() == null && L2vlan.class.equals(update.getType())) {
176 // IfType was missing at creation, add it now
177 add(identifier, update);