Upgrade to OpenROADM 7.1.0 network models
[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.transportpce.common.fixedflex.GridConstant;
29 import org.opendaylight.transportpce.common.fixedflex.GridUtils;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.FrequencyGHz;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.optical.channel.types.rev200529.FrequencyTHz;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev200529.degree.used.wavelengths.UsedWavelengths;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev200529.degree.used.wavelengths.UsedWavelengthsBuilder;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.degree.rev200529.degree.used.wavelengths.UsedWavelengthsKey;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.Node1;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.Node1Builder;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.TerminationPoint1;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.TerminationPoint1Builder;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.node.DegreeAttributes;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.node.DegreeAttributesBuilder;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.node.SrgAttributes;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.node.SrgAttributesBuilder;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.node.termination.point.CpAttributes;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.node.termination.point.CpAttributesBuilder;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.node.termination.point.CtpAttributes;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.node.termination.point.CtpAttributesBuilder;
47 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.node.termination.point.PpAttributes;
48 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.node.termination.point.PpAttributesBuilder;
49 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.node.termination.point.RxTtpAttributes;
50 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.node.termination.point.RxTtpAttributesBuilder;
51 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.node.termination.point.TxTtpAttributes;
52 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.node.termination.point.TxTtpAttributesBuilder;
53 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.node.termination.point.XpdrClientAttributes;
54 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.node.termination.point.XpdrNetworkAttributes;
55 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.node.termination.point.XpdrNetworkAttributesBuilder;
56 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.node.termination.point.XpdrPortAttributes;
57 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.node.termination.point.XpdrPortAttributesBuilder;
58 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.node.termination.point.pp.attributes.UsedWavelength;
59 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.node.termination.point.pp.attributes.UsedWavelengthBuilder;
60 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.networks.network.node.termination.point.pp.attributes.UsedWavelengthKey;
61 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.OpenroadmTpType;
62 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.available.freq.map.AvailFreqMaps;
63 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.available.freq.map.AvailFreqMapsKey;
64 import org.opendaylight.yang.gen.v1.http.org.openroadm.xponder.rev200529.xpdr.port.connection.attributes.Wavelength;
65 import org.opendaylight.yang.gen.v1.http.org.openroadm.xponder.rev200529.xpdr.port.connection.attributes.WavelengthBuilder;
66 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629.PathDescription;
67 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629.path.description.atoz.direction.AToZ;
68 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629.path.description.ztoa.direction.ZToA;
69 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629.pce.resource.resource.resource.TerminationPoint;
70 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NetworkId;
71 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.Networks;
72 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
73 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network;
74 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.NetworkKey;
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.slf4j.Logger;
81 import org.slf4j.LoggerFactory;
82
83 public class NetworkModelWavelengthServiceImpl implements NetworkModelWavelengthService {
84
85     private static final Logger LOG = LoggerFactory.getLogger(NetworkModelWavelengthServiceImpl.class);
86     private final DataBroker dataBroker;
87     private final AvailFreqMapsKey availFreqMapKey = new AvailFreqMapsKey(GridConstant.C_BAND);
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.rev200529
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
176                         .org.openroadm.common.network.rev200529.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.rev200529
194         .Node1> getNode2FromDatastore(String nodeId) {
195         InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Node1>
196                 nodeIID = createNode2IID(nodeId);
197         Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.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         updateFreqMaps4Nodes(nodeIds, wavelengthNumber, true);
210     }
211
212
213
214
215
216     private void deleteAvailableWL(List<String> nodeIds, Long wavelengthNumber) {
217         updateFreqMaps4Nodes(nodeIds, wavelengthNumber, false);
218     }
219
220     private InstanceIdentifierBuilder<TerminationPoint1> createTerminationPoint1IIDBuilder(String nodeId, String tpId) {
221         return InstanceIdentifier
222                 .builder(Networks.class).child(Network.class, new NetworkKey(
223                 new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID))).child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml
224                 .ns.yang.ietf.network.rev180226.networks.network.Node.class, new NodeKey(new NodeId(nodeId)))
225                 .augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
226                 .Node1.class).child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology
227                 .rev180226.networks.network.node.TerminationPoint.class, new TerminationPointKey(new TpId(tpId)))
228                 .augmentation(TerminationPoint1.class);
229     }
230
231     private InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529
232         .TerminationPoint1> createTerminationPoint2IIDBuilder(String nodeId, String tpId) {
233         return InstanceIdentifier
234                 .builder(Networks.class).child(Network.class, new NetworkKey(
235                 new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID))).child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml
236                 .ns.yang.ietf.network.rev180226.networks.network.Node.class, new NodeKey(new NodeId(nodeId)))
237                 .augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
238                 .Node1.class).child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology
239                 .rev180226.networks.network.node.TerminationPoint.class, new TerminationPointKey(new TpId(tpId)))
240                 .augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529
241                     .TerminationPoint1.class);
242     }
243
244     private Optional<TerminationPoint1> getTerminationPoint1FromDatastore(String nodeId, String tpId) {
245         InstanceIdentifier<TerminationPoint1> tpIID = createTerminationPoint1IIDBuilder(nodeId, tpId).build();
246         Optional<TerminationPoint1> tpOpt;
247         try (ReadTransaction readTx = this.dataBroker.newReadOnlyTransaction()) {
248             tpOpt = readTx.read(LogicalDatastoreType.CONFIGURATION, tpIID)
249                     .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
250         } catch (InterruptedException | ExecutionException | TimeoutException e) {
251             LOG.warn("Exception while getting termination point from {} topology!", NetworkUtils.OVERLAY_NETWORK_ID,
252                     e);
253             tpOpt = Optional.empty();
254         }
255         return tpOpt;
256     }
257
258     private Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529
259         .TerminationPoint1> getTerminationPoint2FromDatastore(String nodeId, String tpId) {
260         InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529
261             .TerminationPoint1> tpIID = createTerminationPoint2IIDBuilder(nodeId, tpId).build();
262         Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.TerminationPoint1> tpOpt;
263         try (ReadTransaction readTx = this.dataBroker.newReadOnlyTransaction()) {
264             tpOpt = readTx.read(LogicalDatastoreType.CONFIGURATION, tpIID)
265                     .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
266         } catch (InterruptedException | ExecutionException | TimeoutException e) {
267             LOG.warn("Exception while getting termination point from {} topology!", NetworkUtils.OVERLAY_NETWORK_ID,
268                     e);
269             tpOpt = Optional.empty();
270         }
271         return tpOpt;
272     }
273
274     private void deleteUsedWL(long wavelengthIndex, List<NodeIdPair> tpIds) {
275         WriteTransaction deleteUsedWlTx = this.dataBroker.newWriteOnlyTransaction();
276         for (NodeIdPair idPair : tpIds) {
277             Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529
278                 .TerminationPoint1> tp2Opt = getTerminationPoint2FromDatastore(idPair.getNodeID(), idPair.getTpID());
279
280             OpenroadmTpType tpType;
281             if (tp2Opt.isPresent()) {
282                 tpType = tp2Opt.get().getTpType();
283             } else {
284                 LOG.error("Unable to get termination point {} from topology {}! Skipping removal of used wavelength"
285                         + " for this node.", idPair.getTpID(), NetworkUtils.OVERLAY_NETWORK_ID);
286                 continue;
287             }
288             Optional<TerminationPoint1> tp1Opt = getTerminationPoint1FromDatastore(idPair.getNodeID(),
289                     idPair.getTpID());
290             InstanceIdentifier.InstanceIdentifierBuilder<TerminationPoint1> usedWlIIDBuilder =
291                     createTerminationPoint1IIDBuilder(idPair.getNodeID(), idPair.getTpID());
292             switch (tpType) {
293                 case DEGREETXTTP:
294                 case DEGREETXRXTTP:
295                     deleteUsedWlTx.delete(LogicalDatastoreType.CONFIGURATION,
296                             usedWlIIDBuilder.child(TxTtpAttributes.class).child(UsedWavelengths.class,
297                                     new UsedWavelengthsKey((int)wavelengthIndex)).build());
298                     break;
299
300                 case DEGREERXTTP:
301                     deleteUsedWlTx.delete(LogicalDatastoreType.CONFIGURATION,
302                             usedWlIIDBuilder.child(RxTtpAttributes.class).child(UsedWavelengths.class,
303                                     new UsedWavelengthsKey((int)wavelengthIndex)).build());
304                     break;
305
306                 case DEGREETXCTP:
307                 case DEGREERXCTP:
308                 case DEGREETXRXCTP:
309                     if (tp1Opt.isPresent()) {
310                         TerminationPoint1 tp1 = tp1Opt.get();
311                         TerminationPoint1Builder tp1Builder = new TerminationPoint1Builder(tp1);
312                         CtpAttributesBuilder ctpAttributesBuilder;
313                         if (tp1Builder.getCtpAttributes() != null) {
314                             ctpAttributesBuilder = new CtpAttributesBuilder(tp1Builder.getCtpAttributes());
315                             Map<AvailFreqMapsKey, AvailFreqMaps> availFreqMapsMap = tp1Builder.getCtpAttributes()
316                                     .nonnullAvailFreqMaps();
317                             ctpAttributesBuilder
318                                     .setAvailFreqMaps(updateFreqMaps(wavelengthIndex, availFreqMapsMap, true));
319                             deleteUsedWlTx.merge(LogicalDatastoreType.CONFIGURATION,
320                                     createTerminationPoint1IIDBuilder(idPair.getNodeID(),
321                                             idPair.getTpID()).build(), tp1Builder.build());
322                         }
323                     }
324                     break;
325
326                 case SRGTXCP:
327                 case SRGRXCP:
328                 case SRGTXRXCP:
329                     if (tp1Opt.isPresent()) {
330                         TerminationPoint1 tp1 = tp1Opt.get();
331                         TerminationPoint1Builder tp1Builder = new TerminationPoint1Builder(tp1);
332                         CpAttributesBuilder cpAttributesBuilder;
333                         if (tp1Builder.getCpAttributes() != null) {
334                             cpAttributesBuilder = new CpAttributesBuilder(tp1Builder.getCpAttributes());
335                             Map<AvailFreqMapsKey, AvailFreqMaps> availFreqMapsMap = tp1Builder.getCpAttributes()
336                                     .nonnullAvailFreqMaps();
337                             cpAttributesBuilder
338                                     .setAvailFreqMaps(updateFreqMaps(wavelengthIndex, availFreqMapsMap, true));
339                             deleteUsedWlTx.merge(LogicalDatastoreType.CONFIGURATION,
340                                     createTerminationPoint1IIDBuilder(idPair.getNodeID(),
341                                             idPair.getTpID()).build(), tp1Builder.build());
342                         }
343                     }
344                     break;
345
346                 case SRGTXRXPP:
347                 case SRGRXPP:
348                 case SRGTXPP:
349                     deleteUsedWlTx.delete(LogicalDatastoreType.CONFIGURATION,
350                             usedWlIIDBuilder.child(PpAttributes.class).child(UsedWavelength.class,
351                                     new UsedWavelengthKey((int)wavelengthIndex)).build());
352                     break;
353
354                 case XPONDERNETWORK:
355                     deleteUsedWlTx.delete(LogicalDatastoreType.CONFIGURATION,
356                             usedWlIIDBuilder.child(XpdrNetworkAttributes.class).child(Wavelength.class).build());
357                     break;
358                 case XPONDERCLIENT:
359                     deleteUsedWlTx.delete(LogicalDatastoreType.CONFIGURATION,
360                             usedWlIIDBuilder.child(XpdrClientAttributes.class).child(Wavelength.class).build());
361                     break;
362                 case XPONDERPORT:
363                     deleteUsedWlTx.delete(LogicalDatastoreType.CONFIGURATION,
364                             usedWlIIDBuilder.child(XpdrPortAttributes.class).child(Wavelength.class).build());
365                     break;
366
367                 default:
368                     break;
369             }
370         }
371         try {
372             deleteUsedWlTx.commit().get(Timeouts.DATASTORE_DELETE, TimeUnit.MILLISECONDS);
373         } catch (InterruptedException | ExecutionException | TimeoutException e) {
374             List<String> tpIdsString = tpIds.stream().map(NodeIdPair::toString).collect(Collectors.toList());
375             LOG.error("Unable to delete used WL {} from TPs {}!", wavelengthIndex, String.join(", ", tpIdsString), e);
376         }
377     }
378
379     private void addUsedWL(long wavelengthIndex, List<NodeIdPair> tpIds) {
380         WriteTransaction addUsedWlTx = this.dataBroker.newWriteOnlyTransaction();
381         FixedFlexImpl fixedFlex = new FixedFlexImpl(wavelengthIndex);
382         FrequencyTHz centralTHz = new FrequencyTHz(new BigDecimal(fixedFlex.getCenterFrequency()));
383         Map<AvailFreqMapsKey, AvailFreqMaps> availFreqMapsMap;
384         for (NodeIdPair idPair : tpIds) {
385             Optional<TerminationPoint1> tp1Opt =
386                 getTerminationPoint1FromDatastore(idPair.getNodeID(), idPair.getTpID());
387             TerminationPoint1 tp1 = null;
388             Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529
389                 .TerminationPoint1> tp2Opt = getTerminationPoint2FromDatastore(idPair.getNodeID(), idPair.getTpID());
390             org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.TerminationPoint1 tp2;
391             if (tp2Opt.isPresent()) {
392                 tp2 = tp2Opt.get();
393             } else {
394                 LOG.error(
395                     "Unable to get common-network termination point {} from topology {}! Skip removal of used"
396                     + "wavelength for the node", idPair.getTpID(), NetworkUtils.OVERLAY_NETWORK_ID);
397                 continue;
398             }
399             TerminationPoint1Builder tp1Builder;
400             if (tp1Opt.isPresent()) {
401                 tp1 = tp1Opt.get();
402                 tp1Builder = new TerminationPoint1Builder(tp1);
403             } else {
404                 tp1Builder = new TerminationPoint1Builder();
405             }
406
407             UsedWavelengths usedWaveLength = new UsedWavelengthsBuilder().setIndex((int)wavelengthIndex)
408                 .setFrequency(centralTHz).setWidth(FrequencyGHz.getDefaultInstance("40")).build();
409             switch (tp2.getTpType()) {
410                 case DEGREETXTTP:
411                 case DEGREETXRXTTP:
412                     TxTtpAttributes txTtpAttributes = null;
413                     Map<UsedWavelengthsKey,UsedWavelengths> usedDegreeTxTtpWls;
414                     if (tp1 != null) {
415                         txTtpAttributes = tp1.getTxTtpAttributes();
416                     }
417                     TxTtpAttributesBuilder txTtpAttributesBuilder;
418                     usedDegreeTxTtpWls = new HashMap<>();
419                     if (txTtpAttributes == null) {
420                         txTtpAttributesBuilder = new TxTtpAttributesBuilder();
421                     } else {
422                         txTtpAttributesBuilder = new TxTtpAttributesBuilder(txTtpAttributes);
423                         usedDegreeTxTtpWls.putAll(txTtpAttributesBuilder.getUsedWavelengths());
424                     }
425                     usedDegreeTxTtpWls.put(usedWaveLength.key(),usedWaveLength);
426                     txTtpAttributesBuilder.setUsedWavelengths(usedDegreeTxTtpWls);
427                     tp1Builder.setTxTtpAttributes(txTtpAttributesBuilder.build());
428                     break;
429
430                 case DEGREERXTTP:
431                     RxTtpAttributes rxTtpAttributes = null;
432                     Map<UsedWavelengthsKey,UsedWavelengths> usedDegreeRxTtpWls;
433                     if (tp1 != null) {
434                         rxTtpAttributes = tp1.getRxTtpAttributes();
435                     }
436                     RxTtpAttributesBuilder rxTtpAttributesBuilder;
437                     usedDegreeRxTtpWls = new HashMap<>();
438                     if (rxTtpAttributes == null) {
439                         rxTtpAttributesBuilder = new RxTtpAttributesBuilder();
440                     } else {
441                         rxTtpAttributesBuilder = new RxTtpAttributesBuilder(rxTtpAttributes);
442                         usedDegreeRxTtpWls.putAll(rxTtpAttributesBuilder.getUsedWavelengths());
443                     }
444                     usedDegreeRxTtpWls.put(usedWaveLength.key(),usedWaveLength);
445                     rxTtpAttributesBuilder.setUsedWavelengths(usedDegreeRxTtpWls);
446                     tp1Builder.setRxTtpAttributes(rxTtpAttributesBuilder.build());
447                     break;
448
449                 case DEGREETXCTP:
450                 case DEGREERXCTP:
451                 case DEGREETXRXCTP:
452                     CtpAttributes ctpAttributes = null;
453                     if (tp1 != null) {
454                         ctpAttributes = tp1.getCtpAttributes();
455                     }
456                     CtpAttributesBuilder ctpAttributesBuilder;
457                     if (ctpAttributes == null) {
458                         ctpAttributesBuilder = new CtpAttributesBuilder();
459                     } else {
460                         ctpAttributesBuilder = new CtpAttributesBuilder(ctpAttributes);
461                     }
462                     availFreqMapsMap = ctpAttributesBuilder.getAvailFreqMaps();
463                     ctpAttributesBuilder.setAvailFreqMaps(updateFreqMaps(wavelengthIndex, availFreqMapsMap, false));
464                     tp1Builder.setCtpAttributes(ctpAttributesBuilder.build());
465                     break;
466
467                 case SRGTXCP:
468                 case SRGRXCP:
469                 case SRGTXRXCP:
470                     CpAttributes cpAttributes = null;
471                     if (tp1 != null) {
472                         cpAttributes = tp1.getCpAttributes();
473                     }
474                     CpAttributesBuilder cpAttributesBuilder;
475                     if (cpAttributes == null) {
476                         cpAttributesBuilder = new CpAttributesBuilder();
477                     } else {
478                         cpAttributesBuilder = new CpAttributesBuilder(cpAttributes);
479                     }
480                     availFreqMapsMap = cpAttributesBuilder.getAvailFreqMaps();
481                     cpAttributesBuilder.setAvailFreqMaps(updateFreqMaps(wavelengthIndex, availFreqMapsMap, false));
482                     tp1Builder.setCpAttributes(cpAttributesBuilder.build());
483                     break;
484
485                 case SRGTXRXPP:
486                 case SRGRXPP:
487                 case SRGTXPP:
488                     PpAttributes ppAttributes = null;
489                     Map<UsedWavelengthKey, UsedWavelength> usedDegreePpWls;
490                     if (tp1 != null) {
491                         ppAttributes = tp1.getPpAttributes();
492                     }
493                     PpAttributesBuilder ppAttributesBuilder;
494                     usedDegreePpWls = new HashMap<>();
495                     if (ppAttributes == null) {
496                         ppAttributesBuilder = new PpAttributesBuilder();
497                     } else {
498                         ppAttributesBuilder = new PpAttributesBuilder(ppAttributes);
499                         usedDegreePpWls.putAll(ppAttributesBuilder.getUsedWavelength());
500                     }
501                     UsedWavelength usedDegreeWaveLength = new UsedWavelengthBuilder()
502                             .setIndex((int)wavelengthIndex)
503                             .setFrequency(centralTHz).setWidth(FrequencyGHz.getDefaultInstance("40")).build();
504                     usedDegreePpWls.put(usedDegreeWaveLength.key(),usedDegreeWaveLength);
505                     ppAttributesBuilder.setUsedWavelength(usedDegreePpWls);
506                     tp1Builder.setPpAttributes(ppAttributesBuilder.build());
507                     break;
508
509                 case XPONDERNETWORK:
510                     XpdrNetworkAttributes xpdrNetworkAttributes = null;
511                     if (tp1 != null) {
512                         xpdrNetworkAttributes = tp1.getXpdrNetworkAttributes();
513                     }
514                     XpdrNetworkAttributesBuilder xpdrNetworkAttributesBuilder;
515                     if (xpdrNetworkAttributes == null) {
516                         xpdrNetworkAttributesBuilder = new XpdrNetworkAttributesBuilder();
517                     } else {
518                         xpdrNetworkAttributesBuilder = new XpdrNetworkAttributesBuilder(xpdrNetworkAttributes);
519                     }
520                     Wavelength usedXpdrNetworkWl = new WavelengthBuilder()
521                         .setWidth(FrequencyGHz.getDefaultInstance("40")).setFrequency(centralTHz).build();
522                     tp1Builder.setXpdrNetworkAttributes(xpdrNetworkAttributesBuilder.setWavelength(usedXpdrNetworkWl)
523                         .build());
524                     break;
525                 case XPONDERCLIENT:
526                     break;
527                 case XPONDERPORT:
528                     XpdrPortAttributes xpdrPortAttributes = null;
529                     if (tp1 != null) {
530                         xpdrPortAttributes = tp1.getXpdrPortAttributes();
531                     }
532                     XpdrPortAttributesBuilder xpdrPortAttributesBuilder;
533                     if (xpdrPortAttributes == null) {
534                         xpdrPortAttributesBuilder = new XpdrPortAttributesBuilder();
535                     } else {
536                         xpdrPortAttributesBuilder = new XpdrPortAttributesBuilder(xpdrPortAttributes);
537                     }
538                     Wavelength usedXpdrPortWl = new WavelengthBuilder().setWidth(FrequencyGHz.getDefaultInstance("40"))
539                         .setFrequency(centralTHz).build();
540                     tp1Builder.setXpdrPortAttributes(xpdrPortAttributesBuilder.setWavelength(usedXpdrPortWl)
541                         .build());
542                     break;
543
544                 default:
545                     // TODO skip for now
546                     continue;
547             }
548             addUsedWlTx.put(LogicalDatastoreType.CONFIGURATION, createTerminationPoint1IIDBuilder(idPair.getNodeID(),
549                     idPair.getTpID()).build(), tp1Builder.build());
550         }
551         try {
552             addUsedWlTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
553         } catch (InterruptedException | ExecutionException | TimeoutException e) {
554             List<String> tpIdsString = tpIds.stream().map(NodeIdPair::toString).collect(Collectors.toList());
555             LOG.error("Unable to add used WL {} for TPs {}!", wavelengthIndex, String.join(", ", tpIdsString), e);
556         }
557     }
558
559     /**
560      * Update availFreqMapsMap for wavelengthNumber for nodes in nodeIds.
561      * @param nodeIds List of node id.
562      * @param wavelengthNumber Long
563      * @param isSlotAvailable boolean true if waveLength is available, false otherwise.
564      */
565     //TODO: reduce its Cognitive Complexity from 21 to the 15
566     private void updateFreqMaps4Nodes(List<String> nodeIds, Long wavelengthNumber, boolean isSlotAvailable) {
567         WriteTransaction nodeWriteTx = this.dataBroker.newWriteOnlyTransaction();
568         Map<AvailFreqMapsKey, AvailFreqMaps> availFreqMapsMap;
569         String action = isSlotAvailable ? "addition" : "deletion";
570         for (String nodeId : nodeIds) {
571             Optional<Node1> node1Opt = getNode1FromDatastore(nodeId);
572             Optional<org.opendaylight.yang.gen.v1
573                 .http.org.openroadm.common.network.rev200529.Node1> node2Opt = getNode2FromDatastore(nodeId);
574             if (!node1Opt.isPresent() || !node2Opt.isPresent()) {
575                 LOG.error(
576                         "From topology {} for node id {} -> Get common-network : {} ! "
577                                 + "Get network-topology : {} ! Skipping {} of available wavelength for this node.",
578                         NetworkUtils.OVERLAY_NETWORK_ID, nodeId, node1Opt.isPresent(), node2Opt.isPresent(), action);
579                 continue;
580             }
581             Node1 node1 = node1Opt.get();
582             org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Node1 node2 = node2Opt.get();
583             Node1Builder node1Builder = new Node1Builder(node1);
584             switch (node2.getNodeType()) {
585                 case DEGREE:
586                     DegreeAttributes degreeAttributes = node1.getDegreeAttributes();
587                     DegreeAttributesBuilder degreeAttributesBuilder;
588                     if (degreeAttributes == null) {
589                         degreeAttributesBuilder = new DegreeAttributesBuilder();
590                     } else {
591                         degreeAttributesBuilder = new DegreeAttributesBuilder(degreeAttributes);
592                     }
593                     availFreqMapsMap = degreeAttributesBuilder.getAvailFreqMaps();
594                     degreeAttributesBuilder
595                     .setAvailFreqMaps(updateFreqMaps(wavelengthNumber, availFreqMapsMap, isSlotAvailable));
596                     node1Builder.setDegreeAttributes(degreeAttributesBuilder.build());
597                     break;
598                 case SRG:
599                     SrgAttributes srgAttributes = node1.getSrgAttributes();
600                     SrgAttributesBuilder srgAttributesBuilder;
601                     if (srgAttributes == null) {
602                         srgAttributesBuilder = new SrgAttributesBuilder();
603                     } else {
604                         srgAttributesBuilder = new SrgAttributesBuilder(srgAttributes);
605                     }
606                     availFreqMapsMap = srgAttributesBuilder.getAvailFreqMaps();
607                     srgAttributesBuilder
608                     .setAvailFreqMaps(updateFreqMaps(wavelengthNumber, availFreqMapsMap, isSlotAvailable));
609                     node1Builder.setSrgAttributes(srgAttributesBuilder.build());
610                     break;
611                 default:
612                     LOG.warn("Node type not managed {}", node2.getNodeType());
613                     break;
614             }
615             nodeWriteTx.put(LogicalDatastoreType.CONFIGURATION, createNode1IID(nodeId), node1Builder.build());
616         }
617         try {
618             nodeWriteTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
619         } catch (ExecutionException | TimeoutException e) {
620             LOG.error("Cannot perform {} WL {} for nodes {}!", action, wavelengthNumber, String.join(", ", nodeIds), e);
621         } catch (InterruptedException e) {
622             LOG.error("{} interrupted  WL {} for nodes {}!", action, wavelengthNumber, String.join(", ", nodeIds), e);
623             Thread.currentThread().interrupt();
624         }
625     }
626
627     /**
628      * Update availFreqMapsMap for wavelengthNumber.
629      * @param wavelengthNumber Long
630      * @param availFreqMapsMap Map
631      * @param isSlotAvailable boolean
632      * @return availFreqMapsMap updated for wavelengthNumber.
633      */
634     private Map<AvailFreqMapsKey, AvailFreqMaps> updateFreqMaps(Long wavelengthNumber,
635             Map<AvailFreqMapsKey, AvailFreqMaps> availFreqMapsMap, boolean isSlotAvailable) {
636         byte slotValue = (byte)GridConstant.USED_SLOT_VALUE;
637         if (isSlotAvailable) {
638             slotValue = (byte)GridConstant.AVAILABLE_SLOT_VALUE;
639         }
640         if (availFreqMapsMap == null) {
641             availFreqMapsMap = GridUtils.initFreqMaps4FixedGrid2Available();
642         }
643         AvailFreqMaps availFreqMaps = availFreqMapsMap.get(availFreqMapKey);
644         if (availFreqMaps != null && availFreqMaps.getFreqMap() != null) {
645             int intWlNumber = wavelengthNumber.intValue();
646             if (intWlNumber > 0 && intWlNumber <= availFreqMaps.getFreqMap().length) {
647                 availFreqMaps.getFreqMap()[intWlNumber - 1] = slotValue;
648             }
649         }
650         return availFreqMapsMap;
651     }
652 }