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 org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
17 import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
18 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.PhysicalLayers;
19 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.Links;
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.evc.unis.Uni;
22 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.evc.unis.uni.EvcUniCeVlans;
23 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;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
27 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
31 import com.google.common.base.Optional;
32 import com.google.common.util.concurrent.CheckedFuture;
34 public class EvcUniUtils {
36 private static final Logger logger = LoggerFactory.getLogger(EvcUniUtils.class);
38 public static Link getLink(DataBroker dataBroker, Uni evcUni) {
39 Optional<org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni> optional = MdsalUtils
40 .read(dataBroker, LogicalDatastoreType.CONFIGURATION,
41 MefUtils.getUniInstanceIdentifier(evcUni.getUniId().getValue()));
43 if (!optional.isPresent()) {
44 logger.error("A matching Uni doesn't exist for EvcUni {}", evcUni.getUniId());
48 org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni uni = optional
51 PhysicalLayers physicalLayers = uni.getPhysicalLayers();
52 if (physicalLayers == null) {
53 logger.warn("Uni {} is missing PhysicalLayers", evcUni.getUniId());
57 Links links = physicalLayers.getLinks();
58 if (links == null || links.getLink() == null) {
59 logger.warn("Uni {} is has no links", evcUni.getUniId());
63 Link link = links.getLink().get(0);
67 public static void removeUni(DataBroker dataBroker, Uni data) {
69 String uniId = data.getUniId().getValue();
70 WriteTransaction tx = createTransaction(dataBroker);
72 Link link = EvcUniUtils.getLink(dataBroker, data);
73 uniId = EvcUniUtils.getInterfaceName(link, uniId);
75 logger.info("Removing trunk {}", uniId);
79 Optional<List<EvcUniCeVlan>> ceVlansOptional = getCeVlans(data);
80 if (!ceVlansOptional.isPresent()) {
84 removeTrunkMemberInterfaces(uniId, ceVlansOptional.get(), tx);
85 commitTransaction(tx);
86 } catch (final Exception e) {
87 logger.error("Remove uni failed !", e);
91 public static void addUni(DataBroker dataBroker, Uni data) {
93 String uniId = data.getUniId().getValue();
94 WriteTransaction tx = createTransaction(dataBroker);
95 Link link = EvcUniUtils.getLink(dataBroker, data);
96 String interfaceName = EvcUniUtils.getInterfaceName(link, uniId);
97 addTrunkInterface(interfaceName, getTrunkParentName(link), tx);
99 Optional<List<EvcUniCeVlan>> ceVlansOptional = getCeVlans(data);
100 if (ceVlansOptional.isPresent()) {
101 addTrunkMemberInterfaces(interfaceName, ceVlansOptional.get(), tx);
104 commitTransaction(tx);
105 } catch (final Exception e) {
106 logger.error("Add uni failed !", e);
110 private static void addTrunkInterface(String interfaceName, String parentInterfaceName, WriteTransaction tx) {
111 logger.info("Adding VLAN trunk {} ParentRef {}", interfaceName, parentInterfaceName);
112 Interface trunkInterface = NetvirtUtils.createTrunkInterface(interfaceName, parentInterfaceName);
113 write(trunkInterface, tx);
116 private static void addTrunkMemberInterfaces(String parentInterfaceName, Iterable<EvcUniCeVlan> ceVlans,
117 WriteTransaction tx) {
118 for (EvcUniCeVlan ceVlan : ceVlans) {
119 Object vid = ceVlan.getVid();
120 if (!(vid instanceof Long)) {
121 String errorMessage = String.format("vlan id {} cannot be cast to Long", vid);
122 logger.error(errorMessage);
123 throw new UnsupportedOperationException(errorMessage);
126 Long vlanId = (Long) vid;
127 String interfaceName = NetvirtUtils.getInterfaceNameForVlan(parentInterfaceName, vlanId.toString());
128 logger.info("Adding VLAN trunk-member {} ParentRef {}", interfaceName, parentInterfaceName);
129 Interface trunkMemberInterface = NetvirtUtils.createTrunkMemberInterface(interfaceName, parentInterfaceName,
131 write(trunkMemberInterface, tx);
135 private static void removeTrunkMemberInterfaces(String parentInterfaceName, Iterable<EvcUniCeVlan> ceVlans,
136 WriteTransaction tx) {
137 for (EvcUniCeVlan ceVlan : ceVlans) {
138 Object vid = ceVlan.getVid();
139 if (!(vid instanceof Long)) {
140 String errorMessage = String.format("vlan id {} cannot be cast to Long", vid);
141 logger.error(errorMessage);
142 throw new UnsupportedOperationException(errorMessage);
145 Long vlanId = (Long) vid;
146 String interfaceName = NetvirtUtils.getInterfaceNameForVlan(parentInterfaceName, vlanId.toString());
147 logger.info("Removing VLAN trunk-member {}", interfaceName);
148 delete(interfaceName, tx);
152 private static InstanceIdentifier<Interface> createInterfaceIdentifier(String interfaceName) {
153 return InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName))
157 private static WriteTransaction createTransaction(DataBroker dataBroker) {
158 WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
162 private static void commitTransaction(WriteTransaction tx) {
164 CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
166 } catch (Exception e) {
167 logger.error("failed to commit transaction due to exception ", e);
171 private static void write(Interface iface, WriteTransaction tx) {
172 String interfaceName = iface.getName();
173 InstanceIdentifier<Interface> interfaceIdentifier = createInterfaceIdentifier(interfaceName);
174 tx.put(LogicalDatastoreType.CONFIGURATION, interfaceIdentifier, iface, true);
177 private static void delete(String interfaceName, WriteTransaction tx) {
178 InstanceIdentifier<Interface> interfaceIdentifier = createInterfaceIdentifier(interfaceName);
179 tx.delete(LogicalDatastoreType.CONFIGURATION, interfaceIdentifier);
182 private static String getTrunkParentName(Link link) {
183 String deviceName = link.getDevice().getValue();
184 String interfaceName = link.getInterface().toString();
185 return getDeviceInterfaceName(deviceName, interfaceName);
188 private static Optional<List<EvcUniCeVlan>> getCeVlans(Uni uni) {
189 EvcUniCeVlans ceVlans = uni.getEvcUniCeVlans();
190 if (ceVlans == null) {
191 return Optional.absent();
194 return Optional.fromNullable(ceVlans.getEvcUniCeVlan());
197 public static String getInterfaceName(Link link, String uniId) {
198 String device = link.getDevice().getValue();
199 return getDeviceInterfaceName(device, uniId);
202 public static String getDeviceInterfaceName(String deviceName, String interfaceName) {
203 return deviceName + IfmConstants.OF_URI_SEPARATOR + interfaceName;