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