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