manually cherry pick this patch https://git.opendaylight.org/gerrit/#/c/34579/
[unimgr.git] / impl / src / main / java / org / opendaylight / unimgr / command / EvcUpdateCommand.java
1 /*
2  * Copyright (c) 2016 CableLabs 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.command;
10
11 import java.util.concurrent.ExecutionException;
12
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
15 import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
18 import org.opendaylight.unimgr.api.AbstractCommand;
19 import org.opendaylight.unimgr.impl.UnimgrConstants;
20 import org.opendaylight.unimgr.impl.UnimgrMapper;
21 import org.opendaylight.unimgr.utils.EvcUtils;
22 import org.opendaylight.unimgr.utils.MdsalUtils;
23 import org.opendaylight.unimgr.utils.OvsdbUtils;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.EvcAugmentation;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.UniAugmentation;
28 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link;
29 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
30 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 import com.google.common.base.Optional;
35 import com.google.common.util.concurrent.CheckedFuture;
36
37 public class EvcUpdateCommand extends AbstractCommand<Link> {
38
39     private static final Logger LOG = LoggerFactory.getLogger(EvcUpdateCommand.class);
40
41     public EvcUpdateCommand(final DataBroker dataBroker, final DataTreeModification<Link> updatedEvcLink) {
42         super(dataBroker, updatedEvcLink);
43     }
44
45     @Override
46     public void execute() {
47         final Link evcLink = dataObject.getRootNode().getDataAfter();
48         final EvcAugmentation evc = evcLink.getAugmentation(EvcAugmentation.class);
49         final InstanceIdentifier<Link> evcKey = dataObject.getRootPath().getRootIdentifier();
50         if (evc != null) {
51             // FIXME: For now, we assume that there is 1 uni per
52             // source/destination
53             if ((evc.getUniDest() == null) || evc.getUniDest().isEmpty()) {
54                 LOG.error("Destination UNI cannot be null.");
55                 return;
56             }
57             if ((evc.getUniSource() == null) || evc.getUniSource().isEmpty()) {
58                 LOG.error("Source UNI cannot be null.");
59                 return;
60             }
61
62             final Ipv4Address laterUni1Ip = evc.getUniSource().iterator().next().getIpAddress().getIpv4Address();
63             final Ipv4Address laterUni2Ip = evc.getUniDest().iterator().next().getIpAddress().getIpv4Address();
64             LOG.trace("New EVC created, source IP: {} destination IP {}.", laterUni1Ip, laterUni2Ip);
65
66             final ReadTransaction readTransac = dataBroker.newReadOnlyTransaction();
67             final CheckedFuture<Optional<Link>, ReadFailedException> retFormerEvc = readTransac.read(LogicalDatastoreType.OPERATIONAL, evcKey);
68             EvcAugmentation formerEvc;
69             try {
70                 Optional<Link> optLinks = retFormerEvc.get();
71                 if(optLinks != null && optLinks.isPresent()) {
72                 formerEvc = optLinks.get().getAugmentation(EvcAugmentation.class);
73                 final Ipv4Address formerUni1ip = formerEvc.getUniSource().iterator().next().getIpAddress().getIpv4Address();
74                 final Ipv4Address formerUni2ip = formerEvc.getUniDest().iterator().next().getIpAddress().getIpv4Address();
75
76                 if (formerUni1ip.equals(laterUni1Ip)) {
77                     // do nothing
78                 } else if (formerUni1ip.equals(laterUni2Ip)) {
79                     // do nothing
80                 } else {
81                     LOG.info("{} is not part of the EVC, removing configuration", formerUni1ip);
82                     final InstanceIdentifier<?> formerUniIID = UnimgrMapper.getUniIid(dataBroker, new IpAddress(formerUni1ip), LogicalDatastoreType.OPERATIONAL);
83                     final Optional<Node> formerUni = MdsalUtils.readNode(dataBroker, LogicalDatastoreType.OPERATIONAL, formerUniIID);
84                     EvcUtils.deleteEvcData(dataBroker, formerUni);
85                 }
86                 if (formerUni2ip.equals(laterUni1Ip)) {
87                     // do nothing
88                 } else if (formerUni2ip.equals(laterUni2Ip)) {
89                     // do nothing
90                 } else {
91                     LOG.info("{} is not part of the EVC, removing configuration", formerUni2ip);
92                     final InstanceIdentifier<?> formerUniIID = UnimgrMapper.getUniIid(dataBroker, new IpAddress(formerUni2ip), LogicalDatastoreType.OPERATIONAL);
93                     final Optional<Node> formerUni = MdsalUtils.readNode(dataBroker, LogicalDatastoreType.OPERATIONAL, formerUniIID);
94                     EvcUtils.deleteEvcData(dataBroker, formerUni);
95                 }
96                 }
97             } catch (final InterruptedException | ExecutionException e) {
98                 LOG.error("Failed to retrieve former EVC {}", evcKey, e);
99             }
100
101             InstanceIdentifier<Node> sourceUniIid;
102             InstanceIdentifier<Node> destinationUniIid;
103
104             final InstanceIdentifier<?> iidSource = evc.getUniSource().iterator().next().getUni();
105             if (iidSource != null) {
106                 sourceUniIid = iidSource.firstIdentifierOf(Node.class);
107             } else {
108                 sourceUniIid = UnimgrMapper.getUniIid(dataBroker,
109                         evc.getUniSource().iterator().next().getIpAddress(),
110                         LogicalDatastoreType.OPERATIONAL);
111             }
112             final InstanceIdentifier<?> iidDest = evc.getUniDest().iterator().next().getUni();
113             if (iidDest != null) {
114                 destinationUniIid = iidDest.firstIdentifierOf(Node.class);
115             } else {
116                 destinationUniIid = UnimgrMapper.getUniIid(dataBroker,
117                         evc.getUniDest().iterator().next().getIpAddress(),
118                         LogicalDatastoreType.OPERATIONAL);
119             }
120
121             // Retrieve the source and destination UNIs
122             final Optional<Node> optionalUniSource = MdsalUtils.readNode(dataBroker,
123                     LogicalDatastoreType.OPERATIONAL,
124                     sourceUniIid);
125             final Optional<Node> optionalUniDestination = MdsalUtils.readNode(dataBroker,
126                     LogicalDatastoreType.OPERATIONAL,
127                     destinationUniIid);
128
129             Node uniSource = null;
130             Node uniDestination = null;
131
132             if (optionalUniSource.isPresent() && optionalUniDestination.isPresent()) {
133                 uniSource = optionalUniSource.get();
134                 uniDestination = optionalUniDestination.get();
135
136                 // Retrieve the source and/or destination OVSDB node
137                 final UniAugmentation sourceUniAugmentation =
138                         uniSource.getAugmentation(UniAugmentation.class);
139                 final UniAugmentation destinationUniAugmentation =
140                         uniDestination.getAugmentation(UniAugmentation.class);
141                 final Optional<Node> optionalSourceOvsdbNode =
142                         MdsalUtils.readNode(dataBroker,
143                                 LogicalDatastoreType.OPERATIONAL,
144                                 sourceUniAugmentation
145                                 .getOvsdbNodeRef()
146                                 .getValue());
147                 final Optional<Node> optionalDestinationOvsdbNode =
148                         MdsalUtils.readNode(dataBroker,
149                                 LogicalDatastoreType.OPERATIONAL,
150                                 destinationUniAugmentation
151                                 .getOvsdbNodeRef()
152                                 .getValue());
153                 if (optionalSourceOvsdbNode.isPresent() && optionalDestinationOvsdbNode.isPresent()) {
154                     // Retrieve the source and/or destination bridge
155                     final InstanceIdentifier<Node> sourceBridgeIid =
156                             UnimgrMapper.getOvsdbBridgeNodeIid(optionalSourceOvsdbNode.get());
157                     final Optional<Node> optionalSourceBr = MdsalUtils.readNode(dataBroker,
158                             LogicalDatastoreType.OPERATIONAL,
159                             sourceBridgeIid);
160                     final InstanceIdentifier<Node> destinationBridgeIid =
161                             UnimgrMapper.getOvsdbBridgeNodeIid(optionalDestinationOvsdbNode.get());
162                     final Optional<Node> optionalDestinationBr = MdsalUtils.readNode(dataBroker,
163                             LogicalDatastoreType.OPERATIONAL,
164                             destinationBridgeIid);
165                     //update ovsdb qos-entry and queues with max-rate to match evc ingress BW
166                     OvsdbUtils.updateMaxRate(dataBroker, sourceUniAugmentation, destinationUniAugmentation, evc);
167                     Node sourceBr = null;
168                     Node destinationBr = null;
169                     if (optionalSourceBr.isPresent() && optionalDestinationBr.isPresent()) {
170                         sourceBr = optionalSourceBr.get();
171                         destinationBr = optionalDestinationBr.get();
172
173                         // Creating termination points (OVSDB CONFIG
174                         // datastore)
175                         OvsdbUtils.createTerminationPointNode(dataBroker,
176                                 uniSource.getAugmentation(UniAugmentation.class),
177                                 sourceBr,
178                                 UnimgrConstants.DEFAULT_BRIDGE_NAME,
179                                 UnimgrConstants.DEFAULT_TUNNEL_IFACE);
180
181                         // Create GRE tunnel (OVSDB CONFIG datastore)
182                         OvsdbUtils.createGreTunnel(dataBroker,
183                                 uniSource.getAugmentation(UniAugmentation.class),
184                                 uniDestination.getAugmentation(UniAugmentation.class),
185                                 sourceBr,
186                                 UnimgrConstants.DEFAULT_BRIDGE_NAME,
187                                 UnimgrConstants.DEFAULT_GRE_TUNNEL_NAME);
188
189                         // Create termination points (CONFIG datastore)
190                         OvsdbUtils.createTerminationPointNode(dataBroker,
191                                 uniSource.getAugmentation(UniAugmentation.class),
192                                 destinationBr,
193                                 UnimgrConstants.DEFAULT_BRIDGE_NAME,
194                                 UnimgrConstants.DEFAULT_TUNNEL_IFACE);
195
196                         // Create GRE tunnel (OVSDB CONFIG datastore)
197                         OvsdbUtils.createGreTunnel(dataBroker,
198                                 uniDestination.getAugmentation(UniAugmentation.class),
199                                 uniSource.getAugmentation(UniAugmentation.class), destinationBr,
200                                 UnimgrConstants.DEFAULT_BRIDGE_NAME,
201                                 UnimgrConstants.DEFAULT_GRE_TUNNEL_NAME);
202
203                         // Update EVC
204                         EvcUtils.updateEvcNode(LogicalDatastoreType.CONFIGURATION,
205                                 evcKey,
206                                 evc,
207                                 sourceUniIid,
208                                 destinationUniIid,
209                                 dataBroker);
210                         EvcUtils.updateEvcNode(LogicalDatastoreType.OPERATIONAL,
211                                 evcKey,
212                                 evc,
213                                 sourceUniIid,
214                                 destinationUniIid,
215                                 dataBroker);
216                     } else {
217                         LOG.info("Unable to retrieve the source and/or destination bridge.");
218                     }
219                 } else {
220                     LOG.info("Unable to retrieve the source and/or destination ovsdbNode.");
221                 }
222             } else {
223                 LOG.info("Unable to retrieve the source and/or destination Uni.");
224             }
225         }
226     }
227
228 }