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