2 * Copyright (c) 2016 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.netvirt.neutronvpn;
10 import com.google.common.base.Optional;
12 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
13 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
14 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.genius.mdsalutil.AbstractDataChangeListener;
17 import org.opendaylight.genius.mdsalutil.MDSALUtil;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
26 import org.opendaylight.yangtools.concepts.ListenerRegistration;
27 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
31 import java.util.ArrayList;
32 import java.util.List;
35 public class NeutronSubnetChangeListener extends AbstractDataChangeListener<Subnet> implements AutoCloseable {
36 private static final Logger LOG = LoggerFactory.getLogger(NeutronSubnetChangeListener.class);
38 private ListenerRegistration<DataChangeListener> listenerRegistration;
39 private final DataBroker broker;
40 private NeutronvpnManager nvpnManager;
43 public NeutronSubnetChangeListener(final DataBroker db, NeutronvpnManager nVpnMgr) {
46 nvpnManager = nVpnMgr;
51 public void close() throws Exception {
52 if (listenerRegistration != null) {
54 listenerRegistration.close();
55 } catch (final Exception e) {
56 LOG.error("Error when cleaning up DataChangeListener.", e);
58 listenerRegistration = null;
60 LOG.info("N_Subnet listener Closed");
64 private void registerListener(final DataBroker db) {
66 listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
67 InstanceIdentifier.create(Neutron.class).child(Subnets.class).child(Subnet.class),
68 NeutronSubnetChangeListener.this, DataChangeScope.SUBTREE);
69 } catch (final Exception e) {
70 LOG.error("Neutron Manager Subnet DataChange listener registration fail!", e);
71 throw new IllegalStateException("Neutron Manager Subnet DataChange listener registration failed.", e);
76 protected void add(InstanceIdentifier<Subnet> identifier, Subnet input) {
77 if (LOG.isTraceEnabled()) {
78 LOG.trace("Adding Subnet : key: " + identifier + ", value=" + input);
80 Uuid networkId = input.getNetworkId();
81 Network network = NeutronvpnUtils.getNeutronNetwork(broker, networkId);
82 if (network == null || NeutronvpnUtils.isNetworkTypeVlanOrGre(network)) {
83 //FIXME: This should be removed when support for VLAN and GRE network types is added
84 LOG.error("neutron vpn doesn't support vlan/gre network provider type for the port {} which is part of network {}.",
85 input.getName(), network);
88 handleNeutronSubnetCreated(input.getUuid(), String.valueOf(input.getCidr().getValue()), input.getNetworkId(), input.getTenantId());
89 NeutronvpnUtils.addToSubnetCache(input);
93 protected void remove(InstanceIdentifier<Subnet> identifier, Subnet input) {
94 if (LOG.isTraceEnabled()) {
95 LOG.trace("Removing subnet : key: " + identifier + ", value=" + input);
97 Uuid networkId = input.getNetworkId();
98 Network network = NeutronvpnUtils.getNeutronNetwork(broker, networkId);
99 if (network == null || NeutronvpnUtils.isNetworkTypeVlanOrGre(network)) {
100 //FIXME: This should be removed when support for VLAN and GRE network types is added
101 LOG.error("neutron vpn doesn't support vlan/gre network provider type for the port {} which is part of network {}.",
102 input.getName(), network);
105 handleNeutronSubnetDeleted(input.getUuid(), networkId, null);
106 NeutronvpnUtils.removeFromSubnetCache(input);
110 protected void update(InstanceIdentifier<Subnet> identifier, Subnet original, Subnet update) {
111 if (LOG.isTraceEnabled()) {
112 LOG.trace("Updating Subnet : key: " + identifier + ", original value=" + original + ", update value=" +
115 Uuid networkId = update.getNetworkId();
116 Network network = NeutronvpnUtils.getNeutronNetwork(broker, networkId);
117 if (network == null || NeutronvpnUtils.isNetworkTypeVlanOrGre(network)) {
118 LOG.error("neutron vpn doesn't support vlan/gre network provider type for the port {} which is part of network {}."
119 + " Skipping the processing of Subnet update DCN", update.getName(), network);
122 handleNeutronSubnetUpdated(update.getUuid(), networkId, update.getTenantId());
123 NeutronvpnUtils.addToSubnetCache(update);
126 private void handleNeutronSubnetCreated(Uuid subnetId, String subnetIp, Uuid networkId, Uuid tenantId) {
127 nvpnManager.updateSubnetNode(subnetId, subnetIp, tenantId, networkId, null, null, null);
128 if (networkId != null) {
129 createSubnetToNetworkMapping(subnetId, networkId);
133 private void handleNeutronSubnetDeleted(Uuid subnetId, Uuid networkId, Uuid tenantId) {
134 Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(broker, networkId);
136 nvpnManager.removeSubnetFromVpn(vpnId, subnetId);
138 if (networkId != null) {
139 deleteSubnetToNetworkMapping(subnetId, networkId);
141 nvpnManager.deleteSubnetMapNode(subnetId);
144 private void handleNeutronSubnetUpdated(Uuid subnetId, Uuid networkId, Uuid tenantId) {
145 Uuid oldNetworkId = NeutronvpnUtils.getSubnetmap(broker, subnetId).getNetworkId();
146 if (oldNetworkId != null && !oldNetworkId.equals(networkId)) {
147 deleteSubnetToNetworkMapping(subnetId, oldNetworkId);
149 if (networkId != null && !networkId.equals(oldNetworkId)) {
150 createSubnetToNetworkMapping(subnetId, networkId);
152 nvpnManager.updateSubnetNode(subnetId, null, tenantId, networkId, null, null, null);
155 private void createSubnetToNetworkMapping(Uuid subnetId, Uuid networkId) {
157 InstanceIdentifier networkMapIdentifier = NeutronvpnUtils.buildNetworkMapIdentifier(networkId);
158 Optional<NetworkMap> optionalNetworkMap = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
159 networkMapIdentifier);
160 NetworkMapBuilder nwMapBuilder = null;
161 if (optionalNetworkMap.isPresent()) {
162 nwMapBuilder = new NetworkMapBuilder(optionalNetworkMap.get());
164 nwMapBuilder = new NetworkMapBuilder().setKey(new NetworkMapKey(networkId)).setNetworkId(networkId);
165 LOG.debug("Adding a new network node in NetworkMaps DS for network {}", networkId.getValue());
167 List<Uuid> subnetIdList = nwMapBuilder.getSubnetIdList();
168 if (subnetIdList == null) {
169 subnetIdList = new ArrayList<>();
171 subnetIdList.add(subnetId);
172 nwMapBuilder.setSubnetIdList(subnetIdList);
173 MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, networkMapIdentifier, nwMapBuilder.build());
174 LOG.debug("Created subnet-network mapping for subnet {} network {}", subnetId.getValue(),
175 networkId.getValue());
176 } catch (Exception e) {
177 LOG.error("Create subnet-network mapping failed for subnet {} network {}", subnetId.getValue(),
178 networkId.getValue());
182 private void deleteSubnetToNetworkMapping(Uuid subnetId, Uuid networkId) {
184 InstanceIdentifier networkMapIdentifier = NeutronvpnUtils.buildNetworkMapIdentifier(networkId);
185 Optional<NetworkMap> optionalNetworkMap = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
186 networkMapIdentifier);
187 if (optionalNetworkMap.isPresent()) {
188 NetworkMapBuilder nwMapBuilder = new NetworkMapBuilder(optionalNetworkMap.get());
189 List<Uuid> subnetIdList = nwMapBuilder.getSubnetIdList();
190 if (subnetIdList.remove(subnetId)) {
191 if (subnetIdList.size() == 0) {
192 MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, networkMapIdentifier);
193 LOG.debug("Deleted network node in NetworkMaps DS for network {}", subnetId.getValue(),
194 networkId.getValue());
196 nwMapBuilder.setSubnetIdList(subnetIdList);
197 MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, networkMapIdentifier,
198 nwMapBuilder.build());
199 LOG.debug("Deleted subnet-network mapping for subnet {} network {}", subnetId.getValue(),
200 networkId.getValue());
203 LOG.error("Subnet {} is not mapped to network {}", subnetId.getValue(), networkId.getValue());
206 LOG.error("network {} not present for subnet {} ", networkId, subnetId);
208 } catch (Exception e) {
209 LOG.error("Delete subnet-network mapping failed for subnet {} network {}", subnetId.getValue(),
210 networkId.getValue());