8be48f5e8baa8521d15d1d972f5a0df3c154122f
[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.Collections;
13 import java.util.List;
14
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
17 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
20 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.links.Link;
21 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.Evc;
22 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.unis.Uni;
23 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.unis.uni.EvcUniCeVlans;
24 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.unis.uni.evc.uni.ce.vlans.EvcUniCeVlan;
25 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.EvcType;
26 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.EvcUniRoleType;
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.opendaylight.netvirt.elan.etree.rev160614.EtreeInterface.EtreeInterfaceType;
29 import org.opendaylight.yangtools.concepts.ListenerRegistration;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 import com.google.common.base.Optional;
34
35 public class EvcListener extends UnimgrDataTreeChangeListener<Evc> {
36
37     private static final Logger log = LoggerFactory.getLogger(EvcListener.class);
38     private ListenerRegistration<EvcListener> evcListenerRegistration;
39
40     public EvcListener(final DataBroker dataBroker) {
41         super(dataBroker);
42
43         registerListener();
44     }
45
46     public void registerListener() {
47         try {
48             final DataTreeIdentifier<Evc> dataTreeIid = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
49                     MefUtils.getEvcInstanceIdentifier());
50             evcListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
51             log.info("EvcDataTreeChangeListener created and registered");
52         } catch (final Exception e) {
53             log.error("Evc DataChange listener registration failed !", e);
54             throw new IllegalStateException("Evc registration Listener failed.", e);
55         }
56     }
57
58     @Override
59     public void close() throws Exception {
60         evcListenerRegistration.close();
61     }
62
63     @Override
64     public void add(DataTreeModification<Evc> newDataObject) {
65         if (newDataObject.getRootPath() != null && newDataObject.getRootNode() != null) {
66             log.info("evc {} created", newDataObject.getRootNode().getIdentifier());
67             addEvc(newDataObject);
68         }
69     }
70
71     @Override
72     public void remove(DataTreeModification<Evc> removedDataObject) {
73         if (removedDataObject.getRootPath() != null && removedDataObject.getRootNode() != null) {
74             log.info("evc {} deleted", removedDataObject.getRootNode().getIdentifier());
75             removeEvc(removedDataObject);
76         }
77     }
78
79     @Override
80     public void update(DataTreeModification<Evc> modifiedDataObject) {
81         if (modifiedDataObject.getRootPath() != null && modifiedDataObject.getRootNode() != null) {
82             log.info("evc {} updated", modifiedDataObject.getRootNode().getIdentifier());
83             updateEvc(modifiedDataObject);
84         }
85     }
86
87     private void addEvc(DataTreeModification<Evc> newDataObject) {
88         try {
89             Evc data = newDataObject.getRootNode().getDataAfter();
90             String instanceName = data.getEvcId().getValue();
91             boolean isEtree = data.getEvcType() == EvcType.RootedMultipoint;
92             if (!data.isAdminStateEnabled()) {
93                 log.info("add - evc {} AdminStateEnabled false", data.getEvcId().getValue());
94             } else {
95                 log.info("Adding {} instance: {}", isEtree ? "etree" : "elan", instanceName);
96                 NetvirtUtils.createElanInstance(dataBroker, instanceName, isEtree);
97             }
98             // Create interfaces
99             if (data.getUnis() == null) {
100                 log.info("No UNI's in service {}, exiting", instanceName);
101                 return;
102             }
103             for (Uni uni : data.getUnis().getUni()) {
104                 if (!uni.isAdminStateEnabled()) {
105                     log.info("uni {} AdminStateEnabled false", uni.getUniId().getValue());
106                 } else {
107                     createInterface(instanceName, uni, isEtree);
108                 }
109             }
110         } catch (final Exception e) {
111             log.error("Add evc failed !", e);
112         }
113     }
114
115     private void updateEvc(DataTreeModification<Evc> modifiedDataObject) {
116         try {
117             Evc original = modifiedDataObject.getRootNode().getDataBefore();
118             Evc update = modifiedDataObject.getRootNode().getDataAfter();
119
120             String instanceName = original.getEvcId().getValue();
121             boolean isEtree = update.getEvcType() == EvcType.RootedMultipoint;
122
123             if (!update.isAdminStateEnabled()) {
124                 log.info("update - evc {} AdminStateEnabled false", update.getEvcId().getValue());
125             }
126             log.info("Updating {} instance: {}", isEtree ? "etree" : "elan", instanceName);
127
128             List<Uni> originalUni = original.getUnis() != null ? original.getUnis().getUni() : Collections.emptyList();
129             if (update == null || update.getUnis() == null) {
130                 log.info("update uni is null");
131             }
132             List<Uni> updateUni = update.getUnis().getUni();
133             if (updateUni != null && !updateUni.isEmpty()) {
134                 List<Uni> existingClonedUni = new ArrayList<>();
135                 if (originalUni != null && !originalUni.isEmpty()) {
136                     existingClonedUni.addAll(0, originalUni);
137                     originalUni.removeAll(updateUni);
138                     updateUni.removeAll(existingClonedUni);
139                     // removing the Uni which are not presented in the updated
140                     // List
141                     for (Uni uni : originalUni) {
142                         if (!uni.isAdminStateEnabled()) {
143                             log.info("uni {} AdminStateEnabled false", uni.getUniId().getValue());
144                         } else {
145                             removeElanInterface(instanceName, uni);
146                         }
147                     }
148                 }
149
150                 // Adding the new Uni which are presented in the updated List
151                 if (updateUni.size() > 0) {
152                     for (Uni uni : updateUni) {
153                         if (!uni.isAdminStateEnabled()) {
154                             log.info("uni {} AdminStateEnabled false", uni.getUniId().getValue());
155                         } else {
156                             createInterface(instanceName, uni, isEtree);
157                         }
158                     }
159                 }
160             } else if (originalUni != null && !originalUni.isEmpty()) {
161                 for (Uni uni : originalUni) {
162                     if (!uni.isAdminStateEnabled()) {
163                         log.info("uni {} AdminStateEnabled false", uni.getUniId().getValue());
164                     } else {
165                         removeElanInterface(instanceName, uni);
166                     }
167                 }
168             }
169         } catch (final Exception e) {
170             log.error("Update evc failed !", e);
171         }
172     }
173
174     private void removeEvc(DataTreeModification<Evc> removedDataObject) {
175         try {
176             Evc data = removedDataObject.getRootNode().getDataBefore();
177             if (!data.isAdminStateEnabled()) {
178                 log.info("remove - evc {} AdminStateEnabled false", data.getEvcId().getValue());
179             }
180
181             String instanceName = data.getEvcId().getValue();
182
183             for (Uni uni : data.getUnis().getUni()) {
184                 if (!uni.isAdminStateEnabled()) {
185                     log.info("uni {} AdminStateEnabled false", uni.getUniId().getValue());
186                 } else {
187
188                     removeElanInterface(instanceName, uni);
189                 }
190             }
191
192             log.info("Removing elan instance: " + instanceName);
193             NetvirtUtils.deleteElanInstance(dataBroker, instanceName);
194         } catch (final Exception e) {
195             log.error("Remove evc failed !", e);
196         }
197     }
198
199     private void createInterface(String instanceName, Uni uni, boolean isEtree) {
200         EvcUniUtils.addUni(dataBroker, uni);
201         String interfaceName = uni.getUniId().getValue();
202         EvcUniRoleType role = uni.getRole();
203         EvcUniCeVlans evcUniCeVlans = uni.getEvcUniCeVlans();
204
205         if (evcUniCeVlans != null && evcUniCeVlans.getEvcUniCeVlan() != null
206                 && !evcUniCeVlans.getEvcUniCeVlan().isEmpty()) {
207             for (EvcUniCeVlan x : evcUniCeVlans.getEvcUniCeVlan()) {
208                 interfaceName = NetvirtUtils.getInterfaceNameForVlan(interfaceName, x.getVid().toString());
209
210                 NetvirtUtils.createInterface(dataBroker, instanceName, interfaceName, RoleToInterfaceType(role),
211                         isEtree);
212             }
213         } else {
214             NetvirtUtils.createInterface(dataBroker, instanceName, interfaceName, RoleToInterfaceType(role), isEtree);
215         }
216     }
217
218     private static EtreeInterfaceType RoleToInterfaceType(EvcUniRoleType role) {
219         if (role == EvcUniRoleType.Root) {
220             return EtreeInterfaceType.Root;
221         } else {
222             return EtreeInterfaceType.Leaf;
223         }
224     }
225
226     private void removeElanInterface(String instanceName, Uni uni) {
227         EvcUniUtils.removeUni(dataBroker, uni);
228
229         String uniId = uni.getUniId().getValue();
230         EvcUniCeVlans evcUniCeVlans = uni.getEvcUniCeVlans();
231         String interfaceName = uniId;
232
233         if (evcUniCeVlans != null && !evcUniCeVlans.getEvcUniCeVlan().isEmpty()) {
234             for (EvcUniCeVlan x : evcUniCeVlans.getEvcUniCeVlan()) {
235
236                 interfaceName = NetvirtUtils.getInterfaceNameForVlan(uniId, x.getVid().toString());
237                 log.info("Removing elan interface: " + interfaceName);
238                 NetvirtUtils.deleteElanInterface(dataBroker, instanceName, interfaceName);
239             }
240         } else {
241             log.info("Removing elan interface: " + uniId);
242             NetvirtUtils.deleteElanInterface(dataBroker, instanceName, interfaceName);
243         }
244     }
245 }