disable dpId generation on restart
[unimgr.git] / netvirt / src / main / java / org / opendaylight / unimgr / mef / netvirt / ElanInterfaceListener.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.List;
12 import java.util.Map;
13 import java.util.Optional;
14 import java.util.stream.Collectors;
15 import java.util.stream.Stream;
16
17 import org.apache.commons.lang3.StringUtils;
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
20 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22 import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
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;
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;
25 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.mef.service.choice.evc.choice.evc.UnisBuilder;
26 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;
27 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.UniBuilder;
28 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.UniKey;
29 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.EvcUniCeVlansBuilder;
30 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.EvcUniCeVlanBuilder;
31 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.EvcUniCeVlanKey;
32 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.EvcUniRoleType;
33 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.Identifier45;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan.L2vlanMode;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
39 import org.opendaylight.yangtools.concepts.ListenerRegistration;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 public class ElanInterfaceListener extends UnimgrDataTreeChangeListener<ElanInterfaces> {
44
45     private static final Logger log = LoggerFactory.getLogger(ElanInterfaceListener.class);
46     private ListenerRegistration<ElanInterfaceListener> elanListenerRegistration;
47
48     public ElanInterfaceListener(final DataBroker dataBroker) {
49         super(dataBroker);
50
51         registerListener();
52     }
53
54     public void registerListener() {
55         try {
56             final DataTreeIdentifier<ElanInterfaces> dataTreeIid = new DataTreeIdentifier<>(
57                     LogicalDatastoreType.CONFIGURATION, NetvirtUtils.getElanInterfacesInstanceIdentifier());
58             elanListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
59             log.info("ElanInterfaceDataTreeChangeListener created and registered");
60         } catch (final Exception e) {
61             log.error("ElanInterface DataChange listener registration failed !", e);
62             throw new IllegalStateException("ElanInterface registration Listener failed.", e);
63         }
64     }
65
66     @Override
67     public void close() throws Exception {
68         elanListenerRegistration.close();
69     }
70
71     @Override
72     public void add(DataTreeModification<ElanInterfaces> newDataObject) {
73         log.info("org.opendaylight.unimgr.mef.netvirt.ElanInterfaceListener in add");
74
75         handleUpdatedInterfaces(newDataObject);
76
77     }
78
79     private void handleUpdatedInterfaces(DataTreeModification<ElanInterfaces> newDataObject) {
80         ElanInterfaces instance = newDataObject.getRootNode().getDataAfter();
81         Optional<String> findFirst = instance.getElanInterface().stream().map(x -> x.getElanInstanceName()).findFirst();
82         if (!findFirst.isPresent()) {
83             log.info("empty - exiting");
84             return;
85         }
86         String elanInstanceName = findFirst.get();
87         if (!StringUtils.isNumericSpace(elanInstanceName)) {
88             elanInstanceName = String.valueOf(elanInstanceName.hashCode());
89         }
90
91         com.google.common.base.Optional<Evc> evc = MefUtils.getEvc(dataBroker, elanInstanceName);
92
93         if (MefUtils.isEvcAdminStateEnabled(dataBroker, elanInstanceName)) {
94             log.info("The EVC {} is admin state enabled, ignoring");
95             return;
96         }
97
98         final String instanceName = elanInstanceName;
99         List<Interface> ifaces = instance.getElanInterface().stream()
100                 .map(x -> NetvirtUtils.getIetfInterface(dataBroker, x.getName()))//
101                 .filter(x -> x.isPresent())//
102                 .map(x -> x.get())//
103                 .collect(Collectors.toList());
104
105         if (log.isInfoEnabled()) {
106             log.info("adding unis from interfaces [{}] are not null from [{}] interfaces are: [{}]", ifaces.size(),
107                     instance.getElanInterface().size(),
108                     StringUtils.join(
109                             instance.getElanInterface().stream().map(x -> x.getName()).collect(Collectors.toList()),
110                             ", "));
111
112         }
113         List<String> trunks = ifaces.stream().filter(x -> x.getAugmentation(IfL2vlan.class) != null)//
114                 .filter(x -> x.getAugmentation(IfL2vlan.class).getL2vlanMode() == L2vlanMode.Trunk)//
115                 .map(x -> x.getName()).collect(Collectors.toList());
116
117         Map<String, List<Integer>> vlans = ifaces.stream()//
118                 .filter(x -> x.getAugmentation(IfL2vlan.class) != null)//
119                 .filter(x -> x.getAugmentation(IfL2vlan.class)//
120                         .getL2vlanMode() == L2vlanMode.TrunkMember)//
121                 .collect(//
122                         Collectors.groupingBy(//
123                                 x -> x.getAugmentation(ParentRefs.class).getParentInterface(), //
124                                 Collectors.mapping(//
125                                         x -> x.getAugmentation(IfL2vlan.class).getVlanId().getValue(), //
126                                         Collectors.toList())));
127
128         Unis unisObj = new UnisBuilder()
129                 .setUni(Stream.concat(trunks.stream(), vlans.keySet().stream())
130                         .filter(x -> !MefUtils.EvcUniExists(dataBroker, instanceName, x))
131                         .map(x -> createElanInterfaceToUni(dataBroker, x, vlans.get(x))).collect(Collectors.toList()))
132                 .build();
133         MdsalUtils.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION,
134                 MefUtils.getUnisInstanceIdentifier(elanInstanceName), unisObj);
135     }
136
137     private static Uni createElanInterfaceToUni(DataBroker dataBroker, String name, List<Integer> vlans) {
138         if (log.isInfoEnabled()) {
139             String vlansstr = "null";
140             if (vlans != null) {
141                 vlansstr = StringUtils.join(vlans, ",");
142             }
143             log.info("create uni: {} setAdminStateEnabled false vlans: {}", name, vlansstr);
144         }
145         UniBuilder b = new UniBuilder();
146         b.setAdminStateEnabled(false);
147         Identifier45 _uniId = new Identifier45(name);
148         b.setKey(new UniKey(_uniId));
149         b.setUniId(_uniId);
150         b.setRole(EvcUniRoleType.Root);
151         if (vlans != null) {
152             b.setEvcUniCeVlans(new EvcUniCeVlansBuilder().setEvcUniCeVlan(
153                     vlans.stream().map(x -> new EvcUniCeVlanBuilder().setKey(new EvcUniCeVlanKey(x)).build())
154                             .collect(Collectors.toList()))
155                     .build());
156         }
157         return b.build();
158     }
159
160     @Override
161     public void remove(DataTreeModification<ElanInterfaces> removedDataObject) {
162         log.info("org.opendaylight.unimgr.mef.netvirt.ElanInterfaceListener in remove");
163     }
164
165     @Override
166     public void update(DataTreeModification<ElanInterfaces> modifiedDataObject) {
167         log.info("org.opendaylight.unimgr.mef.netvirt.ElanInterfaceListener in update");
168         handleUpdatedInterfaces(modifiedDataObject);
169     }
170
171 }