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