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