Upgrade Network model from 2.1 to 4.1
[transportpce.git] / renderer / src / main / java / org / opendaylight / transportpce / renderer / NetworkModelWavelengthServiceImpl.java
1 /*
2  * Copyright © 2017 AT&T 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 package org.opendaylight.transportpce.renderer;
9
10 import com.google.common.base.Optional;
11
12 import java.math.BigDecimal;
13 import java.util.ArrayList;
14 import java.util.List;
15 import java.util.concurrent.ExecutionException;
16 import java.util.concurrent.TimeUnit;
17 import java.util.concurrent.TimeoutException;
18 import java.util.stream.Collectors;
19 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
21 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.transportpce.common.NetworkUtils;
24 import org.opendaylight.transportpce.common.Timeouts;
25 import org.opendaylight.transportpce.common.fixedflex.FixedFlexImpl;
26 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev181130.FrequencyGHz;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev181130.FrequencyTHz;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev181130.degree.node.attributes.AvailableWavelengthsKey;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev181130.degree.used.wavelengths.UsedWavelengths;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev181130.degree.used.wavelengths.UsedWavelengthsBuilder;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev181130.degree.used.wavelengths.UsedWavelengthsKey;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.Node1;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.Node1Builder;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.TerminationPoint1;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.TerminationPoint1Builder;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.DegreeAttributes;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.DegreeAttributesBuilder;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.SrgAttributes;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.SrgAttributesBuilder;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.CpAttributes;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.CpAttributesBuilder;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.CtpAttributes;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.CtpAttributesBuilder;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.PpAttributes;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.PpAttributesBuilder;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.RxTtpAttributes;
47 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.RxTtpAttributesBuilder;
48 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.TxTtpAttributes;
49 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.TxTtpAttributesBuilder;
50 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.XpdrClientAttributes;
51 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.XpdrClientAttributesBuilder;
52 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.XpdrNetworkAttributes;
53 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.XpdrNetworkAttributesBuilder;
54 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.XpdrPortAttributes;
55 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.XpdrPortAttributesBuilder;
56 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.pp.attributes.UsedWavelength;
57 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.pp.attributes.UsedWavelengthBuilder;
58 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network.node.termination.point.pp.attributes.UsedWavelengthKey;
59 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmTpType;
60 import org.opendaylight.yang.gen.v1.http.org.openroadm.srg.rev181130.srg.node.attributes.AvailableWavelengthsBuilder;
61 import org.opendaylight.yang.gen.v1.http.org.openroadm.xponder.rev181130.xpdr.port.connection.attributes.Wavelength;
62 import org.opendaylight.yang.gen.v1.http.org.openroadm.xponder.rev181130.xpdr.port.connection.attributes.WavelengthBuilder;
63 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.PathDescription;
64 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.path.description.atoz.direction.AToZ;
65 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.path.description.ztoa.direction.ZToA;
66 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev171017.pce.resource.resource.resource.TerminationPoint;
67 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NetworkId;
68 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.Networks;
69 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
70 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network;
71 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.NetworkKey;
72 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node;
73 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.NodeKey;
74 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.TpId;
75 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPointKey;
76 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
77 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
78 import org.slf4j.Logger;
79 import org.slf4j.LoggerFactory;
80
81 public class NetworkModelWavelengthServiceImpl implements NetworkModelWavelengthService {
82
83     private static final Logger LOG = LoggerFactory.getLogger(NetworkModelWavelengthServiceImpl.class);
84     private final DataBroker dataBroker;
85
86     public NetworkModelWavelengthServiceImpl(DataBroker dataBroker) {
87         this.dataBroker = dataBroker;
88     }
89
90     @Override
91     public void useWavelengths(PathDescription pathDescription) {
92
93         List<NodeIdPair> atozTpIds = getAToZTpList(pathDescription);
94         List<NodeIdPair> ztoaTpIds = getZToATpList(pathDescription);
95
96         deleteAvailableWL(atozTpIds.stream().map(NodeIdPair::getNodeID).distinct().collect(Collectors.toList()),
97                 pathDescription.getAToZDirection().getAToZWavelengthNumber());
98         deleteAvailableWL(ztoaTpIds.stream().map(NodeIdPair::getNodeID).distinct().collect(Collectors.toList()),
99                 pathDescription.getZToADirection().getZToAWavelengthNumber());
100
101         addUsedWL(pathDescription.getAToZDirection().getAToZWavelengthNumber(), atozTpIds);
102         addUsedWL(pathDescription.getZToADirection().getZToAWavelengthNumber(), ztoaTpIds);
103     }
104
105     @Override
106     public void freeWavelengths(PathDescription pathDescription) {
107         List<NodeIdPair> atozTpIds = getAToZTpList(pathDescription);
108         List<NodeIdPair> ztoaTpIds = getZToATpList(pathDescription);
109
110         deleteUsedWL(pathDescription.getAToZDirection().getAToZWavelengthNumber(), atozTpIds);
111         deleteUsedWL(pathDescription.getZToADirection().getZToAWavelengthNumber(), ztoaTpIds);
112
113         addAvailableWL(atozTpIds.stream().map(NodeIdPair::getNodeID).distinct().collect(Collectors.toList()),
114                 pathDescription.getAToZDirection().getAToZWavelengthNumber());
115         addAvailableWL(ztoaTpIds.stream().map(NodeIdPair::getNodeID).distinct().collect(Collectors.toList()),
116                 pathDescription.getZToADirection().getZToAWavelengthNumber());
117     }
118
119     private List<NodeIdPair> getAToZTpList(PathDescription pathDescription) {
120         List<AToZ> atozList = pathDescription.getAToZDirection().getAToZ();
121         return atozList.stream()
122                 .filter(aToZ -> {
123                     if ((aToZ.getResource() == null) || (aToZ.getResource().getResource() == null)) {
124                         LOG.warn("Resource of AToZ node {} is null! Skipping this node!", aToZ.getId());
125                         return false;
126                     }
127                     return aToZ.getResource().getResource() instanceof TerminationPoint;
128                 }).map(aToZ -> {
129                     TerminationPoint tp = (TerminationPoint) aToZ.getResource().getResource();
130                     if ((tp == null) || (tp.getTpNodeId() == null) ||  (tp.getTpId() == null)) {
131                         LOG.warn("Termination point in AToZ node {} contains nulls! Skipping this node!", aToZ.getId());
132                         return null;
133                     }
134                     return new NodeIdPair(tp.getTpNodeId(), tp.getTpId());
135                 }).collect(Collectors.toList());
136     }
137
138     private List<NodeIdPair> getZToATpList(PathDescription pathDescription) {
139         List<ZToA> ztoaList = pathDescription.getZToADirection().getZToA();
140         return ztoaList.stream()
141                 .filter(zToA -> {
142                     if ((zToA.getResource() == null) || (zToA.getResource().getResource() == null)) {
143                         LOG.warn("Resource of ZToA node {} is null! Skipping this node!", zToA.getId());
144                         return false;
145                     }
146                     return zToA.getResource().getResource() instanceof TerminationPoint;
147                 }).map(zToA -> {
148                     TerminationPoint tp = (TerminationPoint) zToA.getResource().getResource();
149                     if ((tp == null) || (tp.getTpNodeId() == null) ||  (tp.getTpId() == null)) {
150                         LOG.warn("Termination point in ZToA node {} contains nulls! Skipping this node!", zToA.getId());
151                         return null;
152                     }
153                     return new NodeIdPair(tp.getTpNodeId(), tp.getTpId());
154                 }).collect(Collectors.toList());
155     }
156
157     private InstanceIdentifier<Node1> createNode1IID(String nodeId) {
158         return InstanceIdentifier
159                 .builder(Networks.class).child(Network.class, new NetworkKey(
160                 new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
161                 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network
162                 .Node.class, new NodeKey(new NodeId(nodeId))).augmentation(Node1.class).build();
163     }
164
165     private Optional<Node1> getNode1FromDatastore(String nodeId) {
166         InstanceIdentifier<Node1>
167                 nodeIID = createNode1IID(nodeId);
168         Optional<Node1> nodeOpt;
169         try (ReadOnlyTransaction nodeReadTx = this.dataBroker.newReadOnlyTransaction()) {
170             nodeOpt = nodeReadTx.read(LogicalDatastoreType.CONFIGURATION, nodeIID)
171                     .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
172         } catch (InterruptedException | ExecutionException | TimeoutException e) {
173             LOG.warn("Exception while getting node from {} topology!", NetworkUtils.OVERLAY_NETWORK_ID, e);
174             nodeOpt = Optional.absent();
175         }
176         return nodeOpt;
177     }
178
179     private void addAvailableWL(List<String> nodeIds, Long wavelengthNumber) {
180         WriteTransaction nodeWriteTx = this.dataBroker.newWriteOnlyTransaction();
181         for (String nodeId : nodeIds) {
182             Optional<Node1> nodeOpt =
183                     getNode1FromDatastore(nodeId);
184             Node1 node;
185             if (nodeOpt.isPresent()) {
186                 node = nodeOpt.get();
187             } else {
188                 LOG.error("Unable to get node {} from topology {}! Skipping addition of available wavelength for this"
189                         + "node.", nodeId, NetworkUtils.OVERLAY_NETWORK_ID);
190                 continue;
191             }
192
193             Node1Builder node1Builder = new Node1Builder(node);
194
195             switch (node.getNodeType()) {
196                 case DEGREE:
197                     DegreeAttributes degreeAttributes = node.getDegreeAttributes();
198                     DegreeAttributesBuilder degreeAttributesBuilder;
199                     if (degreeAttributes == null) {
200                         degreeAttributesBuilder = new DegreeAttributesBuilder();
201                     } else {
202                         degreeAttributesBuilder = new DegreeAttributesBuilder(degreeAttributes);
203                     }
204                     List<org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev181130.degree.node.attributes
205                             .AvailableWavelengths> availableDegreeWLs =
206                             degreeAttributesBuilder.getAvailableWavelengths();
207                     if (availableDegreeWLs == null) {
208                         availableDegreeWLs = new ArrayList<>();
209                         degreeAttributesBuilder.setAvailableWavelengths(availableDegreeWLs);
210                     }
211                     availableDegreeWLs.add(new org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev181130.degree
212                             .node.attributes.AvailableWavelengthsBuilder().setIndex(wavelengthNumber).build());
213                     node1Builder.setDegreeAttributes(degreeAttributesBuilder.build());
214                     break;
215                 case SRG:
216                     SrgAttributes srgAttributes = node.getSrgAttributes();
217                     SrgAttributesBuilder srgAttributesBuilder;
218                     if (srgAttributes == null) {
219                         srgAttributesBuilder = new SrgAttributesBuilder();
220                     } else {
221                         srgAttributesBuilder = new SrgAttributesBuilder(srgAttributes);
222                     }
223                     List<org.opendaylight.yang.gen.v1.http.org.openroadm.srg.rev181130.srg.node.attributes
224                             .AvailableWavelengths> availableSrgWLs = srgAttributesBuilder.getAvailableWavelengths();
225                     if (availableSrgWLs == null) {
226                         availableSrgWLs = new ArrayList<>();
227                         srgAttributesBuilder.setAvailableWavelengths(availableSrgWLs);
228                     }
229                     availableSrgWLs.add(new AvailableWavelengthsBuilder().setIndex(wavelengthNumber).build());
230                     node1Builder.setSrgAttributes(srgAttributesBuilder.build());
231                     break;
232
233                 default:
234                     // TODO skip for now
235                     continue;
236             }
237             nodeWriteTx.put(LogicalDatastoreType.CONFIGURATION, createNode1IID(nodeId), node1Builder.build(), true);
238         }
239         try {
240             nodeWriteTx.submit().get(Timeouts.DATASTORE_DELETE, TimeUnit.MILLISECONDS);
241         } catch (InterruptedException | ExecutionException | TimeoutException e) {
242             LOG.error("Unable to add available WL {} for nodes {}!", wavelengthNumber, String.join(", ", nodeIds), e);
243         }
244     }
245
246     private void deleteAvailableWL(List<String> nodeIds, Long wavelengthNumber) {
247         WriteTransaction nodeWriteTx = this.dataBroker.newWriteOnlyTransaction();
248         for (String nodeId : nodeIds) {
249             Optional<Node1> nodeOpt = getNode1FromDatastore(nodeId);
250             Node1 node;
251             if (nodeOpt.isPresent()) {
252                 node = nodeOpt.get();
253             } else {
254                 LOG.error("Unable to get node {} from topology {}! Skipping addition of available wavelength for this"
255                         + "node.", nodeId, NetworkUtils.OVERLAY_NETWORK_ID);
256                 continue;
257             }
258
259             InstanceIdentifierBuilder<Node1> nodeIIDBuilder = InstanceIdentifier.builder(Networks.class)
260                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)))
261                 .child(Node.class, new NodeKey(new NodeId(nodeId))).augmentation(Node1.class);
262             InstanceIdentifier availableWlIID;
263
264             switch (node.getNodeType()) {
265                 case DEGREE:
266                     availableWlIID = nodeIIDBuilder.child(DegreeAttributes.class)
267                             .child(org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev181130.degree.node
268                                     .attributes.AvailableWavelengths.class,
269                                     new AvailableWavelengthsKey(wavelengthNumber))
270                             .build();
271                     break;
272                 case SRG:
273                     availableWlIID = nodeIIDBuilder.child(SrgAttributes.class)
274                             .child(org.opendaylight.yang.gen.v1.http.org.openroadm.srg.rev181130.srg.node.attributes
275                                             .AvailableWavelengths.class,
276                                     new org.opendaylight.yang.gen.v1.http.org.openroadm.srg.rev181130.srg.node
277                                             .attributes.AvailableWavelengthsKey(wavelengthNumber))
278                             .build();
279                     break;
280
281                 default:
282                     // TODO skip for now
283                     continue;
284             }
285             nodeWriteTx.delete(LogicalDatastoreType.CONFIGURATION, availableWlIID);
286         }
287         try {
288             nodeWriteTx.submit().get(Timeouts.DATASTORE_DELETE, TimeUnit.MILLISECONDS);
289         } catch (InterruptedException | ExecutionException | TimeoutException e) {
290             LOG.error("Unable to delete available WL {} for nodes {}!", wavelengthNumber, String.join(", ", nodeIds),
291                     e);
292         }
293     }
294
295     private InstanceIdentifierBuilder<TerminationPoint1> createTerminationPoint1IIDBuilder(String nodeId, String tpId) {
296         return InstanceIdentifier
297                 .builder(Networks.class).child(Network.class, new NetworkKey(
298                 new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID))).child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml
299                 .ns.yang.ietf.network.rev180226.networks.network.Node.class, new NodeKey(new NodeId(nodeId)))
300                 .augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
301                 .Node1.class).child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology
302                 .rev180226.networks.network.node.TerminationPoint.class, new TerminationPointKey(new TpId(tpId)))
303                 .augmentation(TerminationPoint1.class);
304     }
305
306     private Optional<TerminationPoint1> getTerminationPoint1FromDatastore(String nodeId, String tpId) {
307         InstanceIdentifier<TerminationPoint1> tpIID = createTerminationPoint1IIDBuilder(nodeId, tpId).build();
308         Optional<TerminationPoint1> tpOpt;
309         try (ReadOnlyTransaction readTx = this.dataBroker.newReadOnlyTransaction()) {
310             tpOpt = readTx.read(LogicalDatastoreType.CONFIGURATION, tpIID)
311                     .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
312         } catch (InterruptedException | ExecutionException | TimeoutException e) {
313             LOG.warn("Exception while getting termination point from {} topology!", NetworkUtils.OVERLAY_NETWORK_ID,
314                     e);
315             tpOpt = Optional.absent();
316         }
317         return tpOpt;
318     }
319
320     private void deleteUsedWL(long wavelengthIndex, List<NodeIdPair> tpIds) {
321         WriteTransaction deleteUsedWlTx = this.dataBroker.newWriteOnlyTransaction();
322         for (NodeIdPair idPair : tpIds) {
323             Optional<TerminationPoint1> tpOpt = getTerminationPoint1FromDatastore(idPair.getNodeID(), idPair.getTpID());
324
325             OpenroadmTpType tpType;
326             if (tpOpt.isPresent()) {
327                 tpType = tpOpt.get().getTpType();
328             } else {
329                 LOG.error("Unable to get termination point {} from topology {}! Skipping removal of used wavelength"
330                         + " for this node.", idPair.getTpID(), NetworkUtils.OVERLAY_NETWORK_ID);
331                 continue;
332             }
333             InstanceIdentifier.InstanceIdentifierBuilder<TerminationPoint1> usedWlIIDBuilder =
334                     createTerminationPoint1IIDBuilder(idPair.getNodeID(), idPair.getTpID());
335             InstanceIdentifier usedWlIID;
336             switch (tpType) {
337                 case DEGREETXTTP:
338                 case DEGREETXRXTTP:
339                     usedWlIID = usedWlIIDBuilder.child(TxTtpAttributes.class).child(UsedWavelengths.class,
340                             new UsedWavelengthsKey(wavelengthIndex)).build();
341                     break;
342
343                 case DEGREERXTTP:
344                     usedWlIID = usedWlIIDBuilder.child(RxTtpAttributes.class).child(UsedWavelengths.class,
345                             new UsedWavelengthsKey(wavelengthIndex)).build();
346                     break;
347
348                 case DEGREETXCTP:
349                 case DEGREERXCTP:
350                 case DEGREETXRXCTP:
351                     usedWlIID = usedWlIIDBuilder.child(CtpAttributes.class).child(UsedWavelengths.class,
352                             new UsedWavelengthsKey(wavelengthIndex)).build();
353                     break;
354
355                 case SRGTXCP:
356                 case SRGRXCP:
357                 case SRGTXRXCP:
358                     usedWlIID = usedWlIIDBuilder.child(CpAttributes.class).child(org.opendaylight.yang.gen.v1.http.org
359                         .openroadm.network.topology.rev181130.networks.network.node.termination.point.cp.attributes
360                         .UsedWavelengths.class, new org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology
361                         .rev181130.networks.network.node.termination.point.cp.attributes
362                         .UsedWavelengthsKey(wavelengthIndex)).build();
363                     break;
364
365                 case SRGTXRXPP:
366                 case SRGRXPP:
367                 case SRGTXPP:
368                     usedWlIID = usedWlIIDBuilder.child(PpAttributes.class).child(UsedWavelength.class,
369                             new UsedWavelengthKey(wavelengthIndex)).build();
370                     break;
371
372                 case XPONDERNETWORK:
373                     usedWlIID = usedWlIIDBuilder.child(XpdrNetworkAttributes.class).child(Wavelength.class).build();
374                     break;
375                 case XPONDERCLIENT:
376                     usedWlIID = usedWlIIDBuilder.child(XpdrClientAttributes.class).child(Wavelength.class).build();
377                     break;
378                 case XPONDERPORT:
379                     usedWlIID = usedWlIIDBuilder.child(XpdrPortAttributes.class).child(Wavelength.class).build();
380                     break;
381
382                 default:
383                     // TODO skip for now
384                     continue;
385             }
386             deleteUsedWlTx.delete(LogicalDatastoreType.CONFIGURATION, usedWlIID);
387         }
388         try {
389             deleteUsedWlTx.submit().get(Timeouts.DATASTORE_DELETE, TimeUnit.MILLISECONDS);
390         } catch (InterruptedException | ExecutionException | TimeoutException e) {
391             List<String> tpIdsString = tpIds.stream().map(NodeIdPair::toString).collect(Collectors.toList());
392             LOG.error("Unable to delete used WL {} from TPs {}!", wavelengthIndex, String.join(", ", tpIdsString), e);
393         }
394     }
395
396     private void addUsedWL(long wavelengthIndex, List<NodeIdPair> tpIds) {
397         WriteTransaction addUsedWlTx = this.dataBroker.newWriteOnlyTransaction();
398         FixedFlexImpl fixedFlex = new FixedFlexImpl();
399         fixedFlex.getFixedFlexWaveMapping(wavelengthIndex);
400         FrequencyGHz frequencyGHz = new FrequencyGHz(new BigDecimal(fixedFlex.getWavelength()));
401         FrequencyTHz frequencyTHz = new FrequencyTHz(new BigDecimal(fixedFlex.getCenterFrequency()));
402
403         for (NodeIdPair idPair : tpIds) {
404             Optional<TerminationPoint1> tpOpt = getTerminationPoint1FromDatastore(idPair.getNodeID(), idPair.getTpID());
405
406             TerminationPoint1 tp;
407             if (tpOpt.isPresent()) {
408                 tp = tpOpt.get();
409             } else {
410                 LOG.error("Unable to get termination point {} from topology {}! Skipping removal of used wavelength"
411                         + " for this node.", idPair.getTpID(), NetworkUtils.OVERLAY_NETWORK_ID);
412                 continue;
413             }
414
415             TerminationPoint1Builder tp1Builder = new TerminationPoint1Builder(tp);
416
417             switch (tp.getTpType()) {
418                 case DEGREETXTTP:
419                 case DEGREETXRXTTP:
420                     TxTtpAttributes txTtpAttributes = tp.getTxTtpAttributes();
421                     TxTtpAttributesBuilder txTtpAttributesBuilder;
422                     if (txTtpAttributes == null) {
423                         txTtpAttributesBuilder = new TxTtpAttributesBuilder();
424                     } else {
425                         txTtpAttributesBuilder = new TxTtpAttributesBuilder(txTtpAttributes);
426                     }
427                     List<UsedWavelengths> usedDegreeTxTtpWls = txTtpAttributesBuilder.getUsedWavelengths();
428                     if (usedDegreeTxTtpWls == null) {
429                         usedDegreeTxTtpWls = new ArrayList<>();
430                         txTtpAttributesBuilder.setUsedWavelengths(usedDegreeTxTtpWls);
431                     }
432                     usedDegreeTxTtpWls.add(new UsedWavelengthsBuilder().setIndex(wavelengthIndex).build());
433                     tp1Builder.setTxTtpAttributes(txTtpAttributesBuilder.build());
434                     break;
435
436                 case DEGREERXTTP:
437                     RxTtpAttributes rxTtpAttributes = tp.getRxTtpAttributes();
438                     RxTtpAttributesBuilder rxTtpAttributesBuilder;
439                     if (rxTtpAttributes == null) {
440                         rxTtpAttributesBuilder = new RxTtpAttributesBuilder();
441                     } else {
442                         rxTtpAttributesBuilder = new RxTtpAttributesBuilder(rxTtpAttributes);
443                     }
444                     List<UsedWavelengths> usedDegreeRxTtpWls = rxTtpAttributesBuilder.getUsedWavelengths();
445                     if (usedDegreeRxTtpWls == null) {
446                         usedDegreeRxTtpWls = new ArrayList<>();
447                         rxTtpAttributesBuilder.setUsedWavelengths(usedDegreeRxTtpWls);
448                     }
449                     usedDegreeRxTtpWls.add(new UsedWavelengthsBuilder().setIndex(wavelengthIndex).build());
450                     tp1Builder.setRxTtpAttributes(rxTtpAttributesBuilder.build());
451                     break;
452
453                 case DEGREETXCTP:
454                 case DEGREERXCTP:
455                 case DEGREETXRXCTP:
456                     CtpAttributes ctpAttributes = tp.getCtpAttributes();
457                     CtpAttributesBuilder ctpAttributesBuilder;
458                     if (ctpAttributes == null) {
459                         ctpAttributesBuilder = new CtpAttributesBuilder();
460                     } else {
461                         ctpAttributesBuilder = new CtpAttributesBuilder(ctpAttributes);
462                     }
463                     List<UsedWavelengths> usedDegreeCtpWls = ctpAttributesBuilder.getUsedWavelengths();
464                     if (usedDegreeCtpWls == null) {
465                         usedDegreeCtpWls = new ArrayList<>();
466                         ctpAttributesBuilder.setUsedWavelengths(usedDegreeCtpWls);
467                     }
468                     usedDegreeCtpWls.add(new UsedWavelengthsBuilder().setIndex(wavelengthIndex).build());
469                     tp1Builder.setCtpAttributes(ctpAttributesBuilder.build());
470                     break;
471
472                 case SRGTXCP:
473                 case SRGRXCP:
474                 case SRGTXRXCP:
475                     CpAttributes cpAttributes = tp.getCpAttributes();
476                     CpAttributesBuilder cpAttributesBuilder;
477                     if (cpAttributes == null) {
478                         cpAttributesBuilder = new CpAttributesBuilder();
479                     } else {
480                         cpAttributesBuilder = new CpAttributesBuilder(cpAttributes);
481                     }
482                     List<org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130.networks.network
483                         .node.termination.point.cp.attributes.UsedWavelengths> usedDegreeCpWls = cpAttributesBuilder
484                         .getUsedWavelengths();
485                     if (usedDegreeCpWls == null) {
486                         usedDegreeCpWls = new ArrayList<>();
487                         cpAttributesBuilder.setUsedWavelengths(usedDegreeCpWls);
488                     }
489                     usedDegreeCpWls.add(new org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev181130
490                             .networks.network.node.termination.point.cp.attributes.UsedWavelengthsBuilder()
491                             .setIndex(wavelengthIndex).build());
492                     tp1Builder.setCpAttributes(cpAttributesBuilder.build());
493                     break;
494
495                 case SRGTXRXPP:
496                 case SRGRXPP:
497                 case SRGTXPP:
498                     PpAttributes ppAttributes = tp.getPpAttributes();
499                     PpAttributesBuilder ppAttributesBuilder;
500                     if (ppAttributes == null) {
501                         ppAttributesBuilder = new PpAttributesBuilder();
502                     } else {
503                         ppAttributesBuilder = new PpAttributesBuilder(ppAttributes);
504                     }
505                     List<UsedWavelength> usedDegreePpWls = ppAttributesBuilder.getUsedWavelength();
506                     if (usedDegreePpWls == null) {
507                         usedDegreePpWls = new ArrayList<>();
508                         ppAttributesBuilder.setUsedWavelength(usedDegreePpWls);
509                     }
510                     usedDegreePpWls.add(new UsedWavelengthBuilder().setIndex(wavelengthIndex).build());
511                     tp1Builder.setPpAttributes(ppAttributesBuilder.build());
512                     break;
513
514                 case XPONDERNETWORK:
515                     XpdrNetworkAttributes xpdrNetworkAttributes = tp.getXpdrNetworkAttributes();
516                     XpdrNetworkAttributesBuilder xpdrNetworkAttributesBuilder;
517                     if (xpdrNetworkAttributes == null) {
518                         xpdrNetworkAttributesBuilder = new XpdrNetworkAttributesBuilder();
519                     } else {
520                         xpdrNetworkAttributesBuilder = new XpdrNetworkAttributesBuilder(xpdrNetworkAttributes);
521                     }
522                     Wavelength usedXpdrNetworkWl = new WavelengthBuilder().setWidth(frequencyGHz)
523                         .setFrequency(frequencyTHz).build();
524                     tp1Builder.setXpdrNetworkAttributes(xpdrNetworkAttributesBuilder
525                             .setWavelength(usedXpdrNetworkWl)
526                             .build());
527                     break;
528                 case XPONDERCLIENT:
529                     XpdrClientAttributes xpdrClientAttributes = tp.getXpdrClientAttributes();
530                     XpdrClientAttributesBuilder xpdrClientAttributesBuilder;
531                     if (xpdrClientAttributes == null) {
532                         xpdrClientAttributesBuilder = new XpdrClientAttributesBuilder();
533                     } else {
534                         xpdrClientAttributesBuilder = new XpdrClientAttributesBuilder(xpdrClientAttributes);
535                     }
536                     Wavelength usedXpdrClientWl = new WavelengthBuilder().setWidth(frequencyGHz)
537                         .setFrequency(frequencyTHz).build();
538                     tp1Builder.setXpdrClientAttributes(xpdrClientAttributesBuilder
539                             .setWavelength(usedXpdrClientWl)
540                             .build());
541                     break;
542                 case XPONDERPORT:
543                     XpdrPortAttributes xpdrPortAttributes = tp.getXpdrPortAttributes();
544                     XpdrPortAttributesBuilder xpdrPortAttributesBuilder;
545                     if (xpdrPortAttributes == null) {
546                         xpdrPortAttributesBuilder = new XpdrPortAttributesBuilder();
547                     } else {
548                         xpdrPortAttributesBuilder = new XpdrPortAttributesBuilder(xpdrPortAttributes);
549                     }
550                     Wavelength usedXpdrPortWl = new WavelengthBuilder().setWidth(frequencyGHz)
551                         .setFrequency(frequencyTHz).build();
552                     tp1Builder.setXpdrPortAttributes(xpdrPortAttributesBuilder
553                             .setWavelength(usedXpdrPortWl)
554                             .build());
555                     break;
556
557                 default:
558                     // TODO skip for now
559                     continue;
560             }
561             addUsedWlTx.put(LogicalDatastoreType.CONFIGURATION, createTerminationPoint1IIDBuilder(idPair.getNodeID(),
562                     idPair.getTpID()).build(), tp1Builder.build(), true);
563         }
564         try {
565             addUsedWlTx.submit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
566         } catch (InterruptedException | ExecutionException | TimeoutException e) {
567             List<String> tpIdsString = tpIds.stream().map(NodeIdPair::toString).collect(Collectors.toList());
568             LOG.error("Unable to add used WL {} for TPs {}!", wavelengthIndex, String.join(", ", tpIdsString), e);
569         }
570     }
571 }