Bump versions by 0.1.0 for next dev cycle
[unimgr.git] / netvirt / src / main / java / org / opendaylight / unimgr / mef / netvirt / EvcUniUtils.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
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;
30
31 import com.google.common.base.Optional;
32 import com.google.common.util.concurrent.CheckedFuture;
33
34 public class EvcUniUtils {
35
36     private static final Logger logger = LoggerFactory.getLogger(EvcUniUtils.class);
37
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()));
42
43         if (!optional.isPresent()) {
44             logger.error("A matching Uni doesn't exist for EvcUni {}", evcUni.getUniId());
45             return null;
46         }
47
48         org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni uni = optional
49                 .get();
50
51         PhysicalLayers physicalLayers = uni.getPhysicalLayers();
52         if (physicalLayers == null) {
53             logger.warn("Uni {} is missing PhysicalLayers", evcUni.getUniId());
54             return null;
55         }
56
57         Links links = physicalLayers.getLinks();
58         if (links == null || links.getLink() == null) {
59             logger.warn("Uni {} is has no links", evcUni.getUniId());
60             return null;
61         }
62
63         Link link = links.getLink().get(0);
64         return link;
65     }
66
67     public static void removeUni(DataBroker dataBroker, Uni data) {
68         try {
69             String uniId = data.getUniId().getValue();
70             WriteTransaction tx = createTransaction(dataBroker);
71
72             Link link = EvcUniUtils.getLink(dataBroker, data);
73             uniId = EvcUniUtils.getInterfaceName(link, uniId);
74
75             logger.info("Removing trunk {}", uniId);
76
77             delete(uniId, tx);
78
79             Optional<List<EvcUniCeVlan>> ceVlansOptional = getCeVlans(data);
80             if (!ceVlansOptional.isPresent()) {
81                 return;
82             }
83
84             removeTrunkMemberInterfaces(uniId, ceVlansOptional.get(), tx);
85             commitTransaction(tx);
86         } catch (final Exception e) {
87             logger.error("Remove uni failed !", e);
88         }
89     }
90
91     public static void addUni(DataBroker dataBroker, Uni data) {
92         try {
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);
98
99             Optional<List<EvcUniCeVlan>> ceVlansOptional = getCeVlans(data);
100             if (ceVlansOptional.isPresent()) {
101                 addTrunkMemberInterfaces(interfaceName, ceVlansOptional.get(), tx);
102             }
103
104             commitTransaction(tx);
105         } catch (final Exception e) {
106             logger.error("Add uni failed !", e);
107         }
108     }
109
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);
114     }
115
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);
124             }
125
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,
130                     vlanId.intValue());
131             write(trunkMemberInterface, tx);
132         }
133     }
134
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);
143             }
144
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);
149         }
150     }
151
152     private static InstanceIdentifier<Interface> createInterfaceIdentifier(String interfaceName) {
153         return InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName))
154                 .build();
155     }
156
157     private static WriteTransaction createTransaction(DataBroker dataBroker) {
158         WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
159         return tx;
160     }
161
162     private static void commitTransaction(WriteTransaction tx) {
163         try {
164             CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
165             futures.get();
166         } catch (Exception e) {
167             logger.error("failed to commit transaction due to exception ", e);
168         }
169     }
170
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);
175     }
176
177     private static void delete(String interfaceName, WriteTransaction tx) {
178         InstanceIdentifier<Interface> interfaceIdentifier = createInterfaceIdentifier(interfaceName);
179         tx.delete(LogicalDatastoreType.CONFIGURATION, interfaceIdentifier);
180     }
181
182     private static String getTrunkParentName(Link link) {
183         String deviceName = link.getDevice().getValue();
184         String interfaceName = link.getInterface().toString();
185         return getDeviceInterfaceName(deviceName, interfaceName);
186     }
187
188     private static Optional<List<EvcUniCeVlan>> getCeVlans(Uni uni) {
189         EvcUniCeVlans ceVlans = uni.getEvcUniCeVlans();
190         if (ceVlans == null) {
191             return Optional.absent();
192         }
193
194         return Optional.fromNullable(ceVlans.getEvcUniCeVlan());
195     }
196
197     public static String getInterfaceName(Link link, String uniId) {
198         String device = link.getDevice().getValue();
199         return getDeviceInterfaceName(device, uniId);
200     }
201
202     public static String getDeviceInterfaceName(String deviceName, String interfaceName) {
203         return deviceName + IfmConstants.OF_URI_SEPARATOR + interfaceName;
204     }
205 }