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