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