import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.links.Link;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.MefServices;
-import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.MefService;
import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.Evc;
import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.evc.unis.Uni;
import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.evc.unis.uni.EvcUniCeVlans;
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;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.EvcType;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.EvcUniRoleType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterface.EtreeInterfaceType;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Optional;
+
public class EvcListener extends UnimgrDataTreeChangeListener<Evc> {
private static final Logger log = LoggerFactory.getLogger(EvcListener.class);
Evc data = newDataObject.getRootNode().getDataAfter();
String instanceName = data.getEvcId().getValue();
- log.info("Adding elan instance: " + instanceName);
- NetvirtUtils.createElanInstance(dataBroker, instanceName);
+ boolean isEtree = data.getEvcType() == EvcType.RootedMultipoint;
+
+ log.info("Adding {} instance: {}", isEtree ? "etree" : "elan", instanceName);
+ NetvirtUtils.createElanInstance(dataBroker, instanceName, isEtree);
- // Create elan interfaces
+ // Create interfaces
for (Uni uni : data.getUnis().getUni()) {
- createElanInterface(instanceName, uni);
+ createInterface(instanceName, uni, isEtree);
}
} catch (final Exception e) {
log.error("Add evc failed !", e);
Evc update = modifiedDataObject.getRootNode().getDataAfter();
String instanceName = original.getEvcId().getValue();
+ boolean isEtree = update.getEvcType() == EvcType.RootedMultipoint;
- log.info("Updating elan instance: " + instanceName);
+ log.info("Updating {} instance: {}", isEtree ? "etree" : "elan", instanceName);
List<Uni> originalUni = original.getUnis().getUni();
List<Uni> updateUni = update.getUnis().getUni();
// Adding the new Uni which are presented in the updated List
if (updateUni.size() > 0) {
for (Uni uni : updateUni) {
- createElanInterface(instanceName, uni);
+ createInterface(instanceName, uni, isEtree);
}
}
} else if (originalUni != null && !originalUni.isEmpty()) {
}
}
- private void createElanInterface(String instanceName, Uni uni) {
+ private void createInterface(String instanceName, Uni uni, boolean isEtree) {
EvcUniUtils.addUni(dataBroker, uni);
String uniId = uni.getUniId().getValue();
Link link = EvcUniUtils.getLink(dataBroker, uni);
String interfaceName = EvcUniUtils.getInterfaceName(link, uniId);
+ boolean result = waitForGeniusToUpdateInterface(interfaceName);
+ if (!result) {
+ log.error("State interface {} is missing ifIndex", interfaceName);
+ return;
+ }
+
+ EvcUniRoleType role = uni.getRole();
+
EvcUniCeVlans evcUniCeVlans = uni.getEvcUniCeVlans();
if (evcUniCeVlans != null && !evcUniCeVlans.getEvcUniCeVlan().isEmpty()) {
interfaceName = NetvirtUtils.getInterfaceNameForVlan(interfaceName, x.getVid().toString());
- log.info("Adding elan interface: " + interfaceName);
- NetvirtUtils.createElanInterface(dataBroker, instanceName, interfaceName);
+ log.info("Adding {} interface: {}", isEtree ? "etree" : "elan", interfaceName);
+
+ if (isEtree) {
+ NetvirtUtils.createEtreeInterface(dataBroker, instanceName, interfaceName,
+ RoleToInterfaceType(role));
+ } else {
+ NetvirtUtils.createElanInterface(dataBroker, instanceName, interfaceName);
+ }
+
}
} else {
- log.info("Adding elan interface: " + interfaceName);
- NetvirtUtils.createElanInterface(dataBroker, instanceName, interfaceName);
+ log.info("Adding {} interface: {}", isEtree ? "etree" : "elan", interfaceName);
+ NetvirtUtils.createEtreeInterface(dataBroker, instanceName, interfaceName, RoleToInterfaceType(role));
+ }
+ }
+
+ private boolean waitForGeniusToUpdateInterface(String interfaceName) {
+ int retries = 10;
+
+ while (retries > 0) {
+ Optional<Interface> optional = MdsalUtils.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
+ NetvirtUtils.getStateInterfaceIdentifier(interfaceName));
+
+ Interface stateInterface = optional.get();
+
+ if (stateInterface != null && stateInterface.getIfIndex() != null) {
+ log.info("State interface configured with ifIndex {}", stateInterface.getIfIndex());
+
+ // Wait a bit, because if we continue too soon this will not
+ // work.
+ try {
+ Thread.sleep(3000);
+ } catch (InterruptedException e) {
+ }
+
+ return true;
+ }
+
+ retries -= 1;
+ try {
+ Thread.sleep(1500);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ return false;
+ }
+
+ private static EtreeInterfaceType RoleToInterfaceType(EvcUniRoleType role) {
+ if (role == EvcUniRoleType.Root) {
+ return EtreeInterfaceType.Root;
+ } else {
+ return EtreeInterfaceType.Leaf;
}
}
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.MefTopology;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.Devices;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.devices.Device;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.devices.DeviceKey;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.devices.device.Interfaces;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.topology.rev150526.mef.topology.devices.device.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.Identifier45;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.IetfInterfacesData;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInstanceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterface.EtreeInterfaceType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceKey;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
public class NetvirtUtils {
public final static String VLAN_SEPARATOR = ".";
- public static void createElanInstance(DataBroker dataBroker, String instanceName) {
+ public static void createElanInstance(DataBroker dataBroker, String instanceName, boolean isEtree) {
ElanInstanceBuilder einstBuilder = createElanInstance(instanceName);
+ if (isEtree) {
+ EtreeInstance etreeInstance = new EtreeInstanceBuilder().build();
+ einstBuilder.addAugmentation(EtreeInstance.class, etreeInstance).build();
+ }
+
MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
getElanInstanceInstanceIdentifier(instanceName), einstBuilder.build());
}
getElanInterfaceInstanceIdentifier(interfaceName), einterfaceBuilder.build());
}
+ public static void createEtreeInterface(DataBroker dataBroker, String instanceName, String interfaceName,
+ EtreeInterfaceType type) {
+ ElanInterfaceBuilder einterfaceBuilder = createEtreeInterface(instanceName, interfaceName, type);
+
+ MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
+ getElanInterfaceInstanceIdentifier(interfaceName), einterfaceBuilder.build());
+ }
+
public static void updateElanInstance(DataBroker dataBroker, String instanceName) {
ElanInstanceBuilder einstBuilder = createElanInstance(instanceName);
return einterfaceBuilder;
}
+ private static ElanInterfaceBuilder createEtreeInterface(String instanceName, String interfaceName,
+ EtreeInterfaceType interfaceType) {
+ ElanInterfaceBuilder einterfaceBuilder = new ElanInterfaceBuilder();
+ einterfaceBuilder.setElanInstanceName(instanceName);
+ einterfaceBuilder.setName(interfaceName);
+ EtreeInterface etreeInterface = new EtreeInterfaceBuilder().setEtreeInterfaceType(interfaceType).build();
+ einterfaceBuilder.addAugmentation(EtreeInterface.class, etreeInterface);
+ return einterfaceBuilder;
+ }
+
private static InstanceIdentifier<ElanInstance> getElanInstanceInstanceIdentifier(String instanceName) {
return InstanceIdentifier.builder(ElanInstances.class)
.child(ElanInstance.class, new ElanInstanceKey(instanceName)).build();
return InstanceIdentifier.builder(ElanInterfaces.class)
.child(ElanInterface.class, new ElanInterfaceKey(interfaceName)).build();
}
+
+ public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> getStateInterfaceIdentifier(
+ String interfaceName) {
+ InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> idBuilder = InstanceIdentifier
+ .builder(InterfacesState.class)
+ .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class,
+ new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(
+ interfaceName));
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id = idBuilder
+ .build();
+ return id;
+ }
}