Add l2vpn support for vlans
[unimgr.git] / netvirt / src / main / java / org / opendaylight / unimgr / mef / netvirt / EvcListener.java
1 /*
2  * Copyright (c) 2016 Hewlett Packard Enterprise, Co. 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
9 package org.opendaylight.unimgr.mef.netvirt;
10
11 import java.util.ArrayList;
12 import java.util.List;
13
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
16 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
17 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
18 import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
19 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.links.Link;
20 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.MefServices;
21 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.MefService;
22 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.Evc;
23 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.evc.unis.Uni;
24 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.evc.unis.uni.EvcUniCeVlans;
25 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.evc.unis.uni.evc.uni.ce.vlans.EvcUniCeVlan;
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;
30
31 public class EvcListener extends UnimgrDataTreeChangeListener<Evc> {
32
33     private static final Logger log = LoggerFactory.getLogger(EvcListener.class);
34     private ListenerRegistration<EvcListener> evcListenerRegistration;
35
36     public EvcListener(final DataBroker dataBroker) {
37         super(dataBroker);
38
39         registerListener();
40     }
41
42     public void registerListener() {
43         try {
44             final DataTreeIdentifier<Evc> dataTreeIid = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
45                     MefUtils.getEvcInstanceIdentifier());
46             evcListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
47             log.info("EvcDataTreeChangeListener created and registered");
48         } catch (final Exception e) {
49             log.error("Evc DataChange listener registration failed !", e);
50             throw new IllegalStateException("Evc registration Listener failed.", e);
51         }
52     }
53
54     @Override
55     public void close() throws Exception {
56         evcListenerRegistration.close();
57     }
58
59     @Override
60     public void add(DataTreeModification<Evc> newDataObject) {
61         if (newDataObject.getRootPath() != null && newDataObject.getRootNode() != null) {
62             log.info("evc {} created", newDataObject.getRootNode().getIdentifier());
63             addEvc(newDataObject);
64         }
65     }
66
67     @Override
68     public void remove(DataTreeModification<Evc> removedDataObject) {
69         if (removedDataObject.getRootPath() != null && removedDataObject.getRootNode() != null) {
70             log.info("evc {} deleted", removedDataObject.getRootNode().getIdentifier());
71             removeEvc(removedDataObject);
72         }
73     }
74
75     @Override
76     public void update(DataTreeModification<Evc> modifiedDataObject) {
77         if (modifiedDataObject.getRootPath() != null && modifiedDataObject.getRootNode() != null) {
78             log.info("evc {} updated", modifiedDataObject.getRootNode().getIdentifier());
79             updateEvc(modifiedDataObject);
80         }
81     }
82
83     private void addEvc(DataTreeModification<Evc> newDataObject) {
84         try {
85             Evc data = newDataObject.getRootNode().getDataAfter();
86             String instanceName = data.getEvcId().getValue();
87
88             log.info("Adding elan instance: " + instanceName);
89             NetvirtUtils.createElanInstance(dataBroker, instanceName);
90
91             // Create elan interfaces
92             for (Uni uni : data.getUnis().getUni()) {
93                 createElanInterface(instanceName, uni);
94             }
95         } catch (final Exception e) {
96             log.error("Add evc failed !", e);
97         }
98     }
99
100     private void updateEvc(DataTreeModification<Evc> modifiedDataObject) {
101         try {
102             Evc original = modifiedDataObject.getRootNode().getDataBefore();
103             Evc update = modifiedDataObject.getRootNode().getDataAfter();
104
105             String instanceName = original.getEvcId().getValue();
106
107             log.info("Updating elan instance: " + instanceName);
108
109             List<Uni> originalUni = original.getUnis().getUni();
110             List<Uni> updateUni = update.getUnis().getUni();
111             if (updateUni != null && !updateUni.isEmpty()) {
112                 List<Uni> existingClonedUni = new ArrayList<>();
113                 if (originalUni != null && !originalUni.isEmpty()) {
114                     existingClonedUni.addAll(0, originalUni);
115                     originalUni.removeAll(updateUni);
116                     updateUni.removeAll(existingClonedUni);
117                     // removing the Uni which are not presented in the updated
118                     // List
119                     for (Uni uni : originalUni) {
120                         removeElanInterface(instanceName, uni);
121                     }
122                 }
123
124                 // Adding the new Uni which are presented in the updated List
125                 if (updateUni.size() > 0) {
126                     for (Uni uni : updateUni) {
127                         createElanInterface(instanceName, uni);
128                     }
129                 }
130             } else if (originalUni != null && !originalUni.isEmpty()) {
131                 for (Uni uni : originalUni) {
132                     removeElanInterface(instanceName, uni);
133                 }
134             }
135         } catch (final Exception e) {
136             log.error("Update evc failed !", e);
137         }
138     }
139
140     private void removeEvc(DataTreeModification<Evc> removedDataObject) {
141         try {
142             Evc data = removedDataObject.getRootNode().getDataBefore();
143
144             String instanceName = data.getEvcId().getValue();
145
146             for (Uni uni : data.getUnis().getUni()) {
147                 removeElanInterface(instanceName, uni);
148             }
149
150             log.info("Removing elan instance: " + instanceName);
151             NetvirtUtils.deleteElanInstance(dataBroker, instanceName);
152         } catch (final Exception e) {
153             log.error("Remove evc failed !", e);
154         }
155     }
156
157     private void createElanInterface(String instanceName, Uni uni) {
158         EvcUniUtils.addUni(dataBroker, uni);
159
160         String uniId = uni.getUniId().getValue();
161
162         Link link = EvcUniUtils.getLink(dataBroker, uni);
163         String interfaceName = EvcUniUtils.getInterfaceName(link, uniId);
164
165         EvcUniCeVlans evcUniCeVlans = uni.getEvcUniCeVlans();
166
167         if (evcUniCeVlans != null && !evcUniCeVlans.getEvcUniCeVlan().isEmpty()) {
168             for (EvcUniCeVlan x : evcUniCeVlans.getEvcUniCeVlan()) {
169
170                 interfaceName = NetvirtUtils.getInterfaceNameForVlan(interfaceName, x.getVid().toString());
171
172                 log.info("Adding elan interface: " + interfaceName);
173                 NetvirtUtils.createElanInterface(dataBroker, instanceName, interfaceName);
174             }
175         } else {
176             log.info("Adding elan interface: " + interfaceName);
177             NetvirtUtils.createElanInterface(dataBroker, instanceName, interfaceName);
178         }
179     }
180
181     private void removeElanInterface(String instanceName, Uni uni) {
182         EvcUniUtils.removeUni(dataBroker, uni);
183
184         String uniId = uni.getUniId().getValue();
185         EvcUniCeVlans evcUniCeVlans = uni.getEvcUniCeVlans();
186
187         Link link = EvcUniUtils.getLink(dataBroker, uni);
188         String interfaceName = EvcUniUtils.getInterfaceName(link, uniId);
189
190         if (evcUniCeVlans != null && !evcUniCeVlans.getEvcUniCeVlan().isEmpty()) {
191             for (EvcUniCeVlan x : evcUniCeVlans.getEvcUniCeVlan()) {
192
193                 interfaceName = NetvirtUtils.getInterfaceNameForVlan(uniId, x.getVid().toString());
194                 log.info("Removing elan interface: " + interfaceName);
195                 NetvirtUtils.deleteElanInterface(dataBroker, instanceName, interfaceName);
196             }
197         } else {
198             log.info("Removing elan interface: " + uniId);
199             NetvirtUtils.deleteElanInterface(dataBroker, instanceName, interfaceName);
200         }
201     }
202 }