neutron: unbreak of neutron northbound yang model revise
[vpnservice.git] / neutronvpn / neutronvpn-impl / src / main / java / org / opendaylight / vpnservice / neutronvpn / NeutronSubnetChangeListener.java
1 /*
2  * Copyright (c) 2016 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 package org.opendaylight.vpnservice.neutronvpn;
9
10 import com.google.common.base.Optional;
11
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.vpnservice.mdsalutil.AbstractDataChangeListener;
17 import org.opendaylight.vpnservice.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.rev150712.Neutron;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.networkmaps.NetworkMap;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.networkmaps.NetworkMapBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.networkmaps.NetworkMapKey;
25 import org.opendaylight.yangtools.concepts.ListenerRegistration;
26 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 import java.util.ArrayList;
31 import java.util.List;
32
33
34 public class NeutronSubnetChangeListener extends AbstractDataChangeListener<Subnet> implements AutoCloseable {
35     private static final Logger LOG = LoggerFactory.getLogger(NeutronSubnetChangeListener.class);
36
37     private ListenerRegistration<DataChangeListener> listenerRegistration;
38     private final DataBroker broker;
39     private NeutronvpnManager nvpnManager;
40
41
42     public NeutronSubnetChangeListener(final DataBroker db, NeutronvpnManager nVpnMgr) {
43         super(Subnet.class);
44         broker = db;
45         nvpnManager = nVpnMgr;
46         registerListener(db);
47     }
48
49     @Override
50     public void close() throws Exception {
51         if (listenerRegistration != null) {
52             try {
53                 listenerRegistration.close();
54             } catch (final Exception e) {
55                 LOG.error("Error when cleaning up DataChangeListener.", e);
56             }
57             listenerRegistration = null;
58         }
59         LOG.info("N_Subnet listener Closed");
60     }
61
62
63     private void registerListener(final DataBroker db) {
64         try {
65             listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
66                     InstanceIdentifier.create(Neutron.class).child(Subnets.class).child(Subnet.class),
67                     NeutronSubnetChangeListener.this, DataChangeScope.SUBTREE);
68         } catch (final Exception e) {
69             LOG.error("Neutron Manager Subnet DataChange listener registration fail!", e);
70             throw new IllegalStateException("Neutron Manager Subnet DataChange listener registration failed.", e);
71         }
72     }
73
74     @Override
75     protected void add(InstanceIdentifier<Subnet> identifier, Subnet input) {
76         if (LOG.isTraceEnabled()) {
77             LOG.trace("Adding Subnet : key: " + identifier + ", value=" + input);
78         }
79         handleNeutronSubnetCreated(input.getUuid(), String.valueOf(input.getCidr().getValue()), input.getNetworkId(), input.getTenantId());
80     }
81
82     @Override
83     protected void remove(InstanceIdentifier<Subnet> identifier, Subnet input) {
84         if (LOG.isTraceEnabled()) {
85             LOG.trace("Removing subnet : key: " + identifier + ", value=" + input);
86         }
87         handleNeutronSubnetDeleted(input.getUuid(), input.getNetworkId(), null);
88     }
89
90     @Override
91     protected void update(InstanceIdentifier<Subnet> identifier, Subnet original, Subnet update) {
92         if (LOG.isTraceEnabled()) {
93             LOG.trace("Updating Subnet : key: " + identifier + ", original value=" + original + ", update value=" +
94                     update);
95         }
96         handleNeutronSubnetUpdated(update.getUuid(), update.getNetworkId(), update.getTenantId());
97     }
98
99     private void handleNeutronSubnetCreated(Uuid subnetId, String subnetIp, Uuid networkId, Uuid tenantId) {
100         nvpnManager.updateSubnetNode(subnetId, subnetIp, tenantId, networkId, null, null, null);
101         if (networkId != null && NeutronvpnUtils.getNeutronNetwork(broker, networkId) != null) {
102             createSubnetToNetworkMapping(subnetId, networkId);
103         }
104     }
105
106     private void handleNeutronSubnetDeleted(Uuid subnetId, Uuid networkId, Uuid tenantId) {
107         Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(broker, networkId);
108         if (vpnId != null) {
109             nvpnManager.removeSubnetFromVpn(vpnId, subnetId);
110         }
111         if (networkId != null)  {
112             deleteSubnetToNetworkMapping(subnetId, networkId);
113         }
114         nvpnManager.deleteSubnetMapNode(subnetId);
115     }
116
117     private void handleNeutronSubnetUpdated(Uuid subnetId, Uuid networkId, Uuid tenantId) {
118         Uuid oldNetworkId = NeutronvpnUtils.getSubnetmap(broker, subnetId).getNetworkId();
119         if (oldNetworkId != null && !oldNetworkId.equals(networkId)) {
120             deleteSubnetToNetworkMapping(subnetId, oldNetworkId);
121         }
122         if (networkId != null && !networkId.equals(oldNetworkId)) {
123             createSubnetToNetworkMapping(subnetId, networkId);
124         }
125         nvpnManager.updateSubnetNode(subnetId, null, tenantId, networkId, null, null, null);
126     }
127
128     private void createSubnetToNetworkMapping(Uuid subnetId, Uuid networkId) {
129         try {
130             InstanceIdentifier networkMapIdentifier = NeutronvpnUtils.buildNetworkMapIdentifier(networkId);
131             Optional<NetworkMap> optionalNetworkMap = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
132                     networkMapIdentifier);
133             NetworkMapBuilder nwMapBuilder = null;
134             if (optionalNetworkMap.isPresent()) {
135                 nwMapBuilder = new NetworkMapBuilder(optionalNetworkMap.get());
136             } else {
137                 nwMapBuilder = new NetworkMapBuilder().setKey(new NetworkMapKey(networkId)).setNetworkId(networkId);
138                 LOG.debug("Adding a new network node in NetworkMaps DS for network {}", networkId.getValue());
139             }
140             List<Uuid> subnetIdList = nwMapBuilder.getSubnetIdList();
141             if (subnetIdList == null) {
142                 subnetIdList = new ArrayList<>();
143             }
144             subnetIdList.add(subnetId);
145             nwMapBuilder.setSubnetIdList(subnetIdList);
146             MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, networkMapIdentifier, nwMapBuilder.build());
147             LOG.debug("Created subnet-network mapping for subnet {} network {}", subnetId.getValue(),
148                     networkId.getValue());
149         } catch (Exception e) {
150             LOG.error("Create subnet-network mapping failed for subnet {} network {}", subnetId.getValue(),
151                     networkId.getValue());
152         }
153     }
154
155     private void deleteSubnetToNetworkMapping(Uuid subnetId, Uuid networkId) {
156         try {
157             InstanceIdentifier networkMapIdentifier = NeutronvpnUtils.buildNetworkMapIdentifier(networkId);
158             Optional<NetworkMap> optionalNetworkMap = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
159                     networkMapIdentifier);
160             if (optionalNetworkMap.isPresent()) {
161                 NetworkMapBuilder nwMapBuilder = new NetworkMapBuilder(optionalNetworkMap.get());
162                 List<Uuid> subnetIdList = nwMapBuilder.getSubnetIdList();
163                 if (subnetIdList.remove(subnetId)) {
164                     if (subnetIdList.size() == 0) {
165                         MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, networkMapIdentifier);
166                         LOG.debug("Deleted network node in NetworkMaps DS for network {}", subnetId.getValue(),
167                                 networkId.getValue());
168                     } else {
169                         nwMapBuilder.setSubnetIdList(subnetIdList);
170                         MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, networkMapIdentifier,
171                                 nwMapBuilder.build());
172                         LOG.debug("Deleted subnet-network mapping for subnet {} network {}", subnetId.getValue(),
173                                 networkId.getValue());
174                     }
175                 } else {
176                     LOG.error("Subnet {} is not mapped to network {}", subnetId.getValue(), networkId.getValue());
177                 }
178             } else {
179                 LOG.error("network {} not present for subnet {} ", networkId, subnetId);
180             }
181         } catch (Exception e) {
182             LOG.error("Delete subnet-network mapping failed for subnet {} network {}", subnetId.getValue(),
183                     networkId.getValue());
184         }
185     }
186 }