2 * Copyright (c) 2016 Hewlett Packard Enterprise, Co. 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
9 package org.opendaylight.unimgr.mef.netvirt;
11 import java.util.List;
13 import java.util.Optional;
14 import java.util.stream.Collectors;
15 import java.util.stream.Stream;
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;
43 public class ElanInterfaceListener extends UnimgrDataTreeChangeListener<ElanInterfaces> {
45 private static final Logger log = LoggerFactory.getLogger(ElanInterfaceListener.class);
46 private ListenerRegistration<ElanInterfaceListener> elanListenerRegistration;
48 public ElanInterfaceListener(final DataBroker dataBroker) {
54 public void registerListener() {
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);
67 public void close() throws Exception {
68 elanListenerRegistration.close();
72 public void add(DataTreeModification<ElanInterfaces> newDataObject) {
73 log.info("org.opendaylight.unimgr.mef.netvirt.ElanInterfaceListener in add");
75 handleUpdatedInterfaces(newDataObject);
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");
86 String elanInstanceName = findFirst.get();
87 if (!StringUtils.isNumericSpace(elanInstanceName)) {
88 elanInstanceName = String.valueOf(elanInstanceName.hashCode());
91 com.google.common.base.Optional<Evc> evc = MefUtils.getEvc(dataBroker, elanInstanceName);
93 if (MefUtils.isEvcAdminStateEnabled(dataBroker, elanInstanceName)) {
94 log.info("The EVC {} is admin state enabled, ignoring");
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())//
103 .collect(Collectors.toList());
105 if (log.isInfoEnabled()) {
106 log.info("adding unis from interfaces [{}] are not null from [{}] interfaces are: [{}]", ifaces.size(),
107 instance.getElanInterface().size(),
109 instance.getElanInterface().stream().map(x -> x.getName()).collect(Collectors.toList()),
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());
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)//
122 Collectors.groupingBy(//
123 x -> x.getAugmentation(ParentRefs.class).getParentInterface(), //
124 Collectors.mapping(//
125 x -> x.getAugmentation(IfL2vlan.class).getVlanId().getValue(), //
126 Collectors.toList())));
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()))
133 MdsalUtils.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION,
134 MefUtils.getUnisInstanceIdentifier(elanInstanceName), unisObj);
137 private static Uni createElanInterfaceToUni(DataBroker dataBroker, String name, List<Integer> vlans) {
138 if (log.isInfoEnabled()) {
139 String vlansstr = "null";
141 vlansstr = StringUtils.join(vlans, ",");
143 log.info("create uni: {} setAdminStateEnabled false vlans: {}", name, vlansstr);
145 UniBuilder b = new UniBuilder();
146 b.setAdminStateEnabled(false);
147 Identifier45 _uniId = new Identifier45(name);
148 b.setKey(new UniKey(_uniId));
150 b.setRole(EvcUniRoleType.Root);
152 b.setEvcUniCeVlans(new EvcUniCeVlansBuilder().setEvcUniCeVlan(
153 vlans.stream().map(x -> new EvcUniCeVlanBuilder().setKey(new EvcUniCeVlanKey(x)).build())
154 .collect(Collectors.toList()))
161 public void remove(DataTreeModification<ElanInterfaces> removedDataObject) {
162 log.info("org.opendaylight.unimgr.mef.netvirt.ElanInterfaceListener in remove");
166 public void update(DataTreeModification<ElanInterfaces> modifiedDataObject) {
167 log.info("org.opendaylight.unimgr.mef.netvirt.ElanInterfaceListener in update");
168 handleUpdatedInterfaces(modifiedDataObject);