f2e7776101541a21531caecb5e3ed096803687ba
[transportpce.git] / networkmodel / src / main / java / org / opendaylight / transportpce / networkmodel / service / FrequenciesServiceImpl.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.networkmodel.service;
9
10 import java.util.Arrays;
11 import java.util.BitSet;
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.InstanceIdentifiers;
26 import org.opendaylight.transportpce.common.NetworkUtils;
27 import org.opendaylight.transportpce.common.NodeIdPair;
28 import org.opendaylight.transportpce.common.Timeouts;
29 import org.opendaylight.transportpce.common.fixedflex.GridConstant;
30 import org.opendaylight.transportpce.common.fixedflex.GridUtils;
31 import org.opendaylight.transportpce.networkmodel.util.OpenRoadmTopology;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev181019.ModulationFormat;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.Node1;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.Node1Builder;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.TerminationPoint1;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.TerminationPoint1Builder;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.DegreeAttributes;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.DegreeAttributesBuilder;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.SrgAttributes;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.SrgAttributesBuilder;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.termination.point.CpAttributes;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.termination.point.CpAttributesBuilder;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.termination.point.CtpAttributes;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.termination.point.CtpAttributesBuilder;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.termination.point.PpAttributes;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.termination.point.PpAttributesBuilder;
47 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.termination.point.RxTtpAttributes;
48 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.termination.point.RxTtpAttributesBuilder;
49 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.termination.point.TxTtpAttributes;
50 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.termination.point.TxTtpAttributesBuilder;
51 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.termination.point.XpdrNetworkAttributes;
52 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.termination.point.XpdrNetworkAttributesBuilder;
53 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.termination.point.XpdrPortAttributes;
54 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.node.termination.point.XpdrPortAttributesBuilder;
55 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.available.freq.map.AvailFreqMaps;
56 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.available.freq.map.AvailFreqMapsBuilder;
57 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.available.freq.map.AvailFreqMapsKey;
58 import org.opendaylight.yang.gen.v1.http.org.openroadm.xponder.rev211210.xpdr.port.connection.attributes.WavelengthBuilder;
59 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.AToZDirection;
60 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.ZToADirection;
61 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.resource.resource.TerminationPoint;
62 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
63 import org.opendaylight.yangtools.yang.common.Decimal64;
64 import org.opendaylight.yangtools.yang.common.Uint32;
65 import org.slf4j.Logger;
66 import org.slf4j.LoggerFactory;
67
68 public class FrequenciesServiceImpl implements FrequenciesService {
69
70     private static final Logger LOG = LoggerFactory.getLogger(FrequenciesServiceImpl.class);
71     private final DataBroker dataBroker;
72     private final AvailFreqMapsKey availFreqMapKey = new AvailFreqMapsKey(GridConstant.C_BAND);
73
74     public FrequenciesServiceImpl(DataBroker dataBroker) {
75         this.dataBroker = dataBroker;
76     }
77
78     @Override
79     public void allocateFrequencies(AToZDirection atoZDirection, ZToADirection ztoADirection) {
80         updateFrequencies(atoZDirection, ztoADirection, true);
81     }
82
83
84     @Override
85     public void releaseFrequencies(AToZDirection atoZDirection, ZToADirection ztoADirection) {
86         updateFrequencies(atoZDirection, ztoADirection, false);
87     }
88
89     /**
90      * Update frequency map for nodes and tp in atozDirection and ztoadirection.
91      * @param atoZDirection AToZDirection
92      * @param ztoADirection ZToADirection
93      * @param used used boolean true if frequencies are used, false otherwise.
94      */
95     private void updateFrequencies(AToZDirection atoZDirection, ZToADirection ztoADirection, boolean used) {
96         if (atoZDirection != null && atoZDirection.getAToZMinFrequency() != null) {
97             LOG.info("Update frequencies for a to z direction {}, used {}", atoZDirection, used);
98             List<NodeIdPair> atozTpIds = getAToZTpList(atoZDirection);
99             Decimal64 atozMinFrequency = atoZDirection.getAToZMinFrequency().getValue();
100             Decimal64 atozMaxFrequency = atoZDirection.getAToZMaxFrequency().getValue();
101             ModulationFormat modulationFormat = ModulationFormat.forName(atoZDirection.getModulationFormat());
102             if (modulationFormat == null) {
103                 LOG.error("Unknown modulation format {} for a to z direction, frequencies not updated",
104                         atoZDirection.getModulationFormat());
105                 return;
106             }
107             setFrequencies4Tps(
108                     atozMinFrequency, atozMaxFrequency,
109                     atoZDirection.getRate(), modulationFormat, atozTpIds,
110                     used);
111             setFrequencies4Nodes(
112                     atozMinFrequency, atozMaxFrequency,
113                     atozTpIds.stream().map(NodeIdPair::getNodeID).distinct().collect(Collectors.toList()),
114                     used);
115         }
116         if (ztoADirection != null && ztoADirection.getZToAMinFrequency() != null) {
117             LOG.info("Update frequencies for z to a direction {}, used {}", ztoADirection, used);
118             List<NodeIdPair> ztoaTpIds = getZToATpList(ztoADirection);
119             Decimal64 ztoaMinFrequency = ztoADirection.getZToAMinFrequency().getValue();
120             Decimal64 ztoaMaxFrequency = ztoADirection.getZToAMaxFrequency().getValue();
121             ModulationFormat modulationFormat = ModulationFormat.forName(ztoADirection.getModulationFormat());
122             if (modulationFormat == null) {
123                 LOG.error("Unknown modulation format {} for z to a direction, frequencies not updated",
124                         ztoADirection.getModulationFormat());
125                 return;
126             }
127             setFrequencies4Tps(
128                     ztoaMinFrequency, ztoaMaxFrequency,
129                     ztoADirection.getRate(), modulationFormat, ztoaTpIds,
130                     used);
131             setFrequencies4Nodes(
132                     ztoaMinFrequency, ztoaMaxFrequency,
133                     ztoaTpIds.stream().map(NodeIdPair::getNodeID).distinct().collect(Collectors.toList()),
134                     used);
135         }
136     }
137
138     /**
139      * Get network node with nodeId from datastore.
140      * @param nodeId String
141      * @return Node1, null otherwise.
142      */
143     private Node1 getNetworkNodeFromDatastore(String nodeId) {
144         InstanceIdentifier<Node1> nodeIID = OpenRoadmTopology.createNetworkNodeIID(nodeId);
145         try (ReadTransaction nodeReadTx = this.dataBroker.newReadOnlyTransaction()) {
146             Optional<Node1> optionalNode = nodeReadTx
147                 .read(LogicalDatastoreType.CONFIGURATION, nodeIID)
148                 .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
149             if (optionalNode.isEmpty()) {
150                 LOG.warn("Unable to get network node for node id {} from topology {}",
151                      nodeId, NetworkUtils.OVERLAY_NETWORK_ID);
152                 return null;
153             }
154             return optionalNode.get();
155         } catch (ExecutionException | TimeoutException e) {
156             LOG.warn("Exception while getting network node for node id {} from {} topology",
157                     nodeId, NetworkUtils.OVERLAY_NETWORK_ID, e);
158             return null;
159         } catch (InterruptedException e) {
160             LOG.warn("Getting network node for node id {} from {} topology was interrupted",
161                     nodeId, NetworkUtils.OVERLAY_NETWORK_ID, e);
162             Thread.currentThread().interrupt();
163             return null;
164         }
165     }
166
167     /**
168      * Get common network node with nodeId from datastore.
169      * @param nodeId String
170      * @return Node1, null otherwise.
171      */
172     private org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Node1
173             getCommonNetworkNodeFromDatastore(String nodeId) {
174         InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Node1> nodeIID =
175             OpenRoadmTopology.createCommonNetworkNodeIID(nodeId);
176         try (ReadTransaction nodeReadTx = this.dataBroker.newReadOnlyTransaction()) {
177             Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Node1> optionalNode =
178                 nodeReadTx
179                     .read(LogicalDatastoreType.CONFIGURATION, nodeIID)
180                     .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
181             if (optionalNode.isEmpty()) {
182                 LOG.error("Unable to get common network node for node id {} from topology {}",
183                         nodeId, NetworkUtils.OVERLAY_NETWORK_ID);
184                 return null;
185             }
186             return optionalNode.get();
187         } catch (ExecutionException | TimeoutException e) {
188             LOG.warn("Exception while getting common network node for node id {} from {} topology",
189                     nodeId, NetworkUtils.OVERLAY_NETWORK_ID, e);
190             return null;
191         } catch (InterruptedException e) {
192             LOG.warn("Getting common network node for node id {} from {} topology was interrupted",
193                     nodeId, NetworkUtils.OVERLAY_NETWORK_ID, e);
194             Thread.currentThread().interrupt();
195             return null;
196         }
197     }
198
199     /**
200      * Set frequency map for nodes in nodeIds.
201      * @param atozMinFrequency BigDecimal
202      * @param atozMaxFrequency BigDecimal
203      * @param nodeIds List of node id
204      * @param used boolean true if min and max frequencies are used, false otherwise.
205      */
206     private void setFrequencies4Nodes(Decimal64 atozMinFrequency, Decimal64 atozMaxFrequency,
207             List<String> nodeIds, boolean used) {
208         updateFreqMaps4Nodes(nodeIds, atozMinFrequency, atozMaxFrequency, used);
209     }
210
211
212     /**
213      * Get a network termination point for nodeId and tpId.
214      * @param nodeId String
215      * @param tpId String
216      * @return network termination point, null otherwise
217      */
218     private TerminationPoint1 getNetworkTerminationPointFromDatastore(String nodeId, String tpId) {
219         InstanceIdentifier<TerminationPoint1> tpIID =
220             InstanceIdentifiers.createNetworkTerminationPoint1IIDBuilder(nodeId, tpId);
221         try (ReadTransaction readTx = this.dataBroker.newReadOnlyTransaction()) {
222             Optional<TerminationPoint1> optionalTerminationPoint = readTx
223                     .read(LogicalDatastoreType.CONFIGURATION, tpIID)
224                     .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
225             return optionalTerminationPoint.isEmpty() ? null : optionalTerminationPoint.get();
226         } catch (ExecutionException | TimeoutException e) {
227             LOG.warn("Exception while getting termination {} for node id {} point from {} topology",
228                     tpId, nodeId, NetworkUtils.OVERLAY_NETWORK_ID, e);
229             return null;
230         } catch (InterruptedException e) {
231             LOG.warn("Getting termination {} for node id {} point from {} topology was interrupted",
232                     tpId, nodeId, NetworkUtils.OVERLAY_NETWORK_ID, e);
233             Thread.currentThread().interrupt();
234             return null;
235         }
236     }
237
238     /**
239      * Get a common network termination point for nodeId and tpId.
240      * @param nodeId String
241      * @param tpId String
242      * @return common network termination point, null otherwise
243      */
244     private org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.TerminationPoint1
245             getCommonNetworkTerminationPointFromDatastore(String nodeId, String tpId) {
246         InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.TerminationPoint1>
247             tpIID = OpenRoadmTopology.createCommonNetworkTerminationPointIIDBuilder(nodeId, tpId).build();
248         try (ReadTransaction readTx = this.dataBroker.newReadOnlyTransaction()) {
249             Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.TerminationPoint1>
250                 optionalTerminationPoint = readTx
251                     .read(LogicalDatastoreType.CONFIGURATION, tpIID)
252                     .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
253             if (optionalTerminationPoint.isEmpty()) {
254                 LOG.error("Unable to get common-network termination point {} for node id {}from topology {}",
255                         tpId, nodeId, NetworkUtils.OVERLAY_NETWORK_ID);
256                 return null;
257             }
258             return optionalTerminationPoint.get();
259         } catch (ExecutionException | TimeoutException e) {
260             LOG.warn("Exception while getting common-network termination {} for node id {} point from {} topology",
261                     tpId, nodeId, NetworkUtils.OVERLAY_NETWORK_ID, e);
262             return null;
263         } catch (InterruptedException e) {
264             LOG.warn("Getting common-network termination {} for node id {} point from {} topology was interrupted",
265                     tpId, nodeId, NetworkUtils.OVERLAY_NETWORK_ID, e);
266             Thread.currentThread().interrupt();
267             return null;
268         }
269     }
270
271     /**
272      * Update availFreqMapsMap for min and max frequencies for termination point in tpIds.
273      * @param atozMinFrequency BigDecimal
274      * @param atozMaxFrequency BigDecimal
275      * @param rate Uint32
276      * @param modulationFormat ModulationFormat
277      * @param tpIds List of NodeIdPair
278      * @param sed boolean true if min and max frequencies are used, false otherwise.
279      */
280     private void setFrequencies4Tps(Decimal64 atozMinFrequency, Decimal64 atozMaxFrequency, Uint32 rate,
281             ModulationFormat modulationFormat, List<NodeIdPair> tpIds, boolean used) {
282         String strTpIdsList = String.join(", ", tpIds.stream().map(NodeIdPair::toString).collect(Collectors.toList()));
283         LOG.debug(
284             "Update frequencies for termination points {}, rate {}, modulation format {},"
285                 + " min frequency {}, max frequency {}, used {}",
286             strTpIdsList, rate, modulationFormat, atozMinFrequency, atozMaxFrequency, used);
287         WriteTransaction updateFrequenciesTransaction = this.dataBroker.newWriteOnlyTransaction();
288         for (NodeIdPair idPair : tpIds) {
289             org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.TerminationPoint1
290                     commonNetworkTerminationPoint =
291                 getCommonNetworkTerminationPointFromDatastore(idPair.getNodeID(), idPair.getTpID());
292             if (commonNetworkTerminationPoint == null) {
293                 LOG.warn("Cannot update frequencies for termination point {}, node id {}",
294                     idPair.getTpID(), idPair.getNodeID());
295                 continue;
296             }
297             TerminationPoint1 networkTerminationPoint =
298                     getNetworkTerminationPointFromDatastore(idPair.getNodeID(), idPair.getTpID());
299             TerminationPoint1Builder networkTerminationPointBuilder =
300                 networkTerminationPoint == null
301                     ? new TerminationPoint1Builder()
302                     : new TerminationPoint1Builder(networkTerminationPoint);
303             switch (commonNetworkTerminationPoint.getTpType()) {
304                 case DEGREETXTTP:
305                 case DEGREETXRXTTP:
306                     networkTerminationPointBuilder.setTxTtpAttributes(updateTxTtpAttributes(networkTerminationPoint,
307                             atozMinFrequency,atozMaxFrequency,used));
308                     break;
309                 case DEGREERXTTP:
310                     networkTerminationPointBuilder.setRxTtpAttributes(updateRxTtpAttributes(networkTerminationPoint,
311                             atozMinFrequency,atozMaxFrequency,used));
312                     break;
313                 case DEGREETXCTP:
314                 case DEGREERXCTP:
315                 case DEGREETXRXCTP:
316                     networkTerminationPointBuilder.setCtpAttributes(updateCtpAttributes(networkTerminationPoint,
317                             atozMinFrequency,atozMaxFrequency,used));
318                     break;
319                 case SRGTXCP:
320                 case SRGRXCP:
321                 case SRGTXRXCP:
322                     networkTerminationPointBuilder.setCpAttributes(updateCpAttributes(networkTerminationPoint,
323                             atozMinFrequency,atozMaxFrequency,used));
324                     break;
325                 case SRGTXRXPP:
326                 case SRGRXPP:
327                 case SRGTXPP:
328                     networkTerminationPointBuilder.setPpAttributes(updatePpAttributes(networkTerminationPoint,
329                             atozMinFrequency,atozMaxFrequency,used));
330                     break;
331                 case XPONDERNETWORK:
332                     networkTerminationPointBuilder.setXpdrNetworkAttributes(
333                             updateXpdrNetworkAttributes(networkTerminationPoint,
334                                     atozMinFrequency, atozMaxFrequency, rate, modulationFormat, used)).build();
335                     break;
336                 case XPONDERCLIENT:
337                     break;
338                 case XPONDERPORT:
339                     networkTerminationPointBuilder.setXpdrPortAttributes(
340                             updateXpdrPortAttributes(networkTerminationPoint,
341                                     atozMinFrequency, atozMaxFrequency, rate, modulationFormat, used)).build();
342                     break;
343                 default:
344                     LOG.warn("Termination point type {} not managed", commonNetworkTerminationPoint.getTpType());
345                     return;
346             }
347             updateFrequenciesTransaction.put(LogicalDatastoreType.CONFIGURATION, InstanceIdentifiers
348                     .createNetworkTerminationPoint1IIDBuilder(idPair.getNodeID(),
349                             idPair.getTpID()), networkTerminationPointBuilder.build());
350         }
351         try {
352             updateFrequenciesTransaction.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
353         } catch (ExecutionException | TimeoutException e) {
354             LOG.error(
355                 "Something went wrong for frequencies update (min frequency {}, max frequency {}, used {} for TPs {}",
356                 atozMinFrequency, atozMaxFrequency, used, strTpIdsList, e);
357         } catch (InterruptedException e) {
358             LOG.error("Frequencies update (min frequency {}, max frequency {}, used {} for TPs {} was interrupted",
359                     atozMinFrequency, atozMaxFrequency, used,
360                     strTpIdsList, e);
361             Thread.currentThread().interrupt();
362         }
363     }
364
365     /**
366      * Update availFreqMapsMap for min and max frequencies for nodes in nodeIds.
367      * @param nodeIds  List of node id
368      * @param atozMinFrequency BigDecimal
369      * @param atozMaxFrequency BigDecimal
370      * @param used boolean true if min and max frequencies are used, false otherwise.
371      */
372     private void updateFreqMaps4Nodes(List<String> nodeIds, Decimal64 atozMinFrequency, Decimal64 atozMaxFrequency,
373             boolean used) {
374         String strNodesList = String.join(", ", nodeIds);
375         LOG.debug("Update frequencies for nodes {}, min frequency {}, max frequency {}, used {}",
376                 strNodesList, atozMinFrequency, atozMaxFrequency, used);
377         WriteTransaction updateFrequenciesTransaction = this.dataBroker.newWriteOnlyTransaction();
378         for (String nodeId : nodeIds) {
379             Node1 networkNode = getNetworkNodeFromDatastore(nodeId);
380             org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Node1 commonNetworkNode =
381                     getCommonNetworkNodeFromDatastore(nodeId);
382             if (networkNode == null || commonNetworkNode == null) {
383                 LOG.warn(
384                         "From topology {} for node id {} -> Get common-network : {} "
385                                 + "Get network-topology : {}. Skipping frequencies update for this node.",
386                         NetworkUtils.OVERLAY_NETWORK_ID, nodeId, commonNetworkNode, networkNode);
387                 continue;
388             }
389             Node1Builder networkNodeBuilder = new Node1Builder(networkNode);
390             switch (commonNetworkNode.getNodeType()) {
391                 case DEGREE:
392                     networkNodeBuilder.setDegreeAttributes(
393                             updateDegreeAttributes(networkNode.getDegreeAttributes(), atozMinFrequency,
394                                     atozMaxFrequency, used));
395                     break;
396                 case SRG:
397                     networkNodeBuilder.setSrgAttributes(updateSrgAttributes(
398                             networkNode.getSrgAttributes(), atozMinFrequency, atozMaxFrequency, used));
399                     break;
400                 default:
401                     LOG.warn("Node type not managed {}", commonNetworkNode.getNodeType());
402                     break;
403             }
404             updateFrequenciesTransaction.put(LogicalDatastoreType.CONFIGURATION,
405                     OpenRoadmTopology.createNetworkNodeIID(nodeId), networkNodeBuilder.build());
406         }
407         try {
408             updateFrequenciesTransaction.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
409         } catch (ExecutionException | TimeoutException e) {
410             LOG.error("Cannot update frequencies {} {} for nodes {}", atozMinFrequency, atozMaxFrequency,
411                     strNodesList, e);
412         } catch (InterruptedException e) {
413             LOG.error("Update of frequencies {} {} for nodes {} was interrupted", atozMinFrequency, atozMaxFrequency,
414                     strNodesList, e);
415             Thread.currentThread().interrupt();
416         }
417     }
418
419     /**
420      * Get list of NodeIdPair from atoZDirection.
421      * @param atoZDirection AToZDirection
422      * @return List of NodeIdPair
423      */
424     private List<NodeIdPair> getAToZTpList(AToZDirection atoZDirection) {
425         return atoZDirection.nonnullAToZ().values().stream()
426                 .filter(aToZ -> {
427                     if (aToZ.getResource() == null || aToZ.getResource().getResource() == null) {
428                         LOG.warn("Resource of AToZ node {} is null! Skipping this node!", aToZ.getId());
429                         return false;
430                     }
431                     return aToZ.getResource().getResource() instanceof TerminationPoint;
432                 }).map(aToZ -> {
433                     TerminationPoint tp = (TerminationPoint) aToZ.getResource().getResource();
434                     if (tp == null || tp.getTpNodeId() == null || tp.getTpId() == null || tp.getTpId().isEmpty()) {
435                         LOG.warn("Termination point in AToZ node {} contains nulls! Skipping this node!", aToZ.getId());
436                         return null;
437                     }
438                     return new NodeIdPair(tp.getTpNodeId(), tp.getTpId());
439                 }).filter(Objects::nonNull)
440                 .collect(Collectors.toList());
441     }
442
443     /**
444      * Get list of NodeIdPair from ztoADirection.
445      * @param ztoADirection ZToADirection
446      * @return List of NodeIdPair
447      */
448     private List<NodeIdPair> getZToATpList(ZToADirection ztoADirection) {
449         return ztoADirection.nonnullZToA().values().stream()
450                 .filter(zToA -> {
451                     if (zToA.getResource() == null || zToA.getResource().getResource() == null) {
452                         LOG.warn("Resource of ZToA node {} is null! Skipping this node!", zToA.getId());
453                         return false;
454                     }
455                     return zToA.getResource().getResource() instanceof TerminationPoint;
456                 }).map(zToA -> {
457                     TerminationPoint tp = (TerminationPoint) zToA.getResource().getResource();
458                     if (tp == null || tp.getTpNodeId() == null || tp.getTpId() == null || tp.getTpId().isEmpty()) {
459                         LOG.warn("Termination point in ZToA node {} contains nulls! Skipping this node!", zToA.getId());
460                         return null;
461                     }
462                     return new NodeIdPair(tp.getTpNodeId(), tp.getTpId());
463                 }).filter(Objects::nonNull)
464                 .collect(Collectors.toList());
465     }
466
467     /**
468      * Update Wavelength for xpdr port attributes.
469      * @param networkTerminationPoint TerminationPoint1
470      * @param atozMinFrequency BigDecimal
471      * @param atozMaxFrequency BigDecimal
472      * @param rate Uint32
473      * @param modulationFormat ModulationFormat
474      * @param used boolean true if min and max frequencies are used, false otherwise.
475      * @return XpdrPortAttributes with Wavelength updated
476      */
477     private XpdrPortAttributes updateXpdrPortAttributes(TerminationPoint1 networkTerminationPoint,
478             Decimal64 atozMinFrequency, Decimal64 atozMaxFrequency, Uint32 rate, ModulationFormat modulationFormat,
479             boolean used) {
480         LOG.debug("Update xpdr node attributes for termination point {}, min frequency {}, max frequency {}, used {}",
481                 networkTerminationPoint, atozMinFrequency, atozMaxFrequency, used);
482         XpdrPortAttributesBuilder xpdrPortAttributesBuilder =
483             networkTerminationPoint == null
484                 ? new XpdrPortAttributesBuilder()
485                 : new XpdrPortAttributesBuilder(networkTerminationPoint.getXpdrPortAttributes());
486         return xpdrPortAttributesBuilder
487             .setWavelength(
488                 used
489                     ? new WavelengthBuilder()
490                         .setWidth(GridUtils.getWidthFromRateAndModulationFormat(rate, modulationFormat))
491                         .setFrequency(
492                             GridUtils.getCentralFrequency(
493                                 atozMinFrequency.decimalValue(),
494                                 atozMaxFrequency.decimalValue()))
495                         .build()
496                     : new WavelengthBuilder().build())
497             .build();
498     }
499
500     /**
501      * Update Wavelength for xpdr network attributes.
502      * @param networkTerminationPoint TerminationPoint1
503      * @param atozMinFrequency BigDecimal
504      * @param atozMaxFrequency BigDecimal
505      * @param rate Uint32
506      * @param modulationFormat ModulationFormat
507      * @param used boolean true if min and max frequencies are used, false otherwise.
508      * @return XpdrNetworkAttributes with Wavelength updated
509      */
510     private XpdrNetworkAttributes updateXpdrNetworkAttributes(TerminationPoint1 networkTerminationPoint,
511             Decimal64 atozMinFrequency, Decimal64 atozMaxFrequency, Uint32 rate, ModulationFormat modulationFormat,
512             boolean used) {
513         LOG.debug("Update xpdr node attributes for termination point {}, min frequency {}, max frequency {}, used {}",
514                 networkTerminationPoint, atozMinFrequency, atozMaxFrequency, used);
515         XpdrNetworkAttributesBuilder xpdrNetworkAttributesBuilder =
516             networkTerminationPoint == null
517                 ? new XpdrNetworkAttributesBuilder()
518                 : new XpdrNetworkAttributesBuilder(networkTerminationPoint.getXpdrNetworkAttributes());
519         return xpdrNetworkAttributesBuilder
520             .setWavelength(
521                 used
522                     ? new WavelengthBuilder()
523                         .setWidth(GridUtils.getWidthFromRateAndModulationFormat(rate, modulationFormat))
524                         .setFrequency(
525                             GridUtils.getCentralFrequency(
526                                 atozMinFrequency.decimalValue(),
527                                 atozMaxFrequency.decimalValue()))
528                         .build()
529                     : null)
530             .build();
531
532     }
533
534     /**
535      * Update freqMaps for pp attributes.
536      * @param networkTerminationPoint TerminationPoint1
537      * @param atozMinFrequency BigDecimal
538      * @param atozMaxFrequency BigDecimal
539      * @param used boolean true if min and max frequencies are used, false otherwise.
540      * @return PpAttributes with frequency map updated
541      */
542     private PpAttributes updatePpAttributes(TerminationPoint1 networkTerminationPoint, Decimal64 atozMinFrequency,
543             Decimal64 atozMaxFrequency, boolean used) {
544         LOG.debug("Update pp attributes for termination point {}, min frequency {}, max frequency {}, used {}",
545                 networkTerminationPoint, atozMinFrequency, atozMaxFrequency, used);
546         PpAttributesBuilder ppAttributesBuilder =
547             networkTerminationPoint == null
548                 ? new PpAttributesBuilder()
549                 : new PpAttributesBuilder(networkTerminationPoint.getPpAttributes());
550         return ppAttributesBuilder
551             .setAvailFreqMaps(
552                 updateFreqMaps(
553                     atozMinFrequency, atozMaxFrequency,
554                     ppAttributesBuilder.getAvailFreqMaps(),
555                     used))
556             .build();
557     }
558
559     /**
560      * Update freqMaps for cp attributes.
561      * @param networkTerminationPoint TerminationPoint1
562      * @param atozMinFrequency BigDecimal
563      * @param atozMaxFrequency BigDecimal
564      * @param used boolean true if min and max frequencies are used, false otherwise.
565      * @return CpAttributes with frequency map updated
566      */
567     private CpAttributes updateCpAttributes(TerminationPoint1 networkTerminationPoint, Decimal64 atozMinFrequency,
568             Decimal64 atozMaxFrequency, boolean used) {
569         LOG.debug("Update cp attributes for termination point {}, min frequency {}, max frequency {}, used {}",
570                 networkTerminationPoint, atozMinFrequency, atozMaxFrequency, used);
571         CpAttributesBuilder cpAttributesBuilder =
572             networkTerminationPoint == null
573                 ? new CpAttributesBuilder()
574                 : new CpAttributesBuilder(networkTerminationPoint.getCpAttributes());
575         return cpAttributesBuilder
576             .setAvailFreqMaps(
577                 updateFreqMaps(
578                     atozMinFrequency, atozMaxFrequency,
579                     cpAttributesBuilder.getAvailFreqMaps(),
580                     used))
581             .build();
582     }
583
584     /**
585      * Update freqMaps for ctp attributes.
586      * @param networkTerminationPoint TerminationPoint1
587      * @param atozMinFrequency BigDecimal
588      * @param atozMaxFrequency BigDecimal
589      * @param used boolean true if min and max frequencies are used, false otherwise.
590      * @return CtpAttributes with frequency map updated
591      */
592     private CtpAttributes updateCtpAttributes(TerminationPoint1 networkTerminationPoint, Decimal64 atozMinFrequency,
593             Decimal64 atozMaxFrequency, boolean used) {
594         LOG.debug("Update ctp attributes for termination point {}, min frequency {}, max frequency {}, used {}",
595                 networkTerminationPoint, atozMinFrequency, atozMaxFrequency, used);
596         CtpAttributesBuilder ctpAttributesBuilder =
597             networkTerminationPoint == null
598                 ?  new CtpAttributesBuilder()
599                 :  new CtpAttributesBuilder(networkTerminationPoint.getCtpAttributes());
600         return ctpAttributesBuilder
601             .setAvailFreqMaps(
602                 updateFreqMaps(
603                     atozMinFrequency, atozMaxFrequency,
604                     ctpAttributesBuilder.getAvailFreqMaps(),
605                     used))
606             .build();
607     }
608
609     /**
610      * Update freqMaps for rxtp attributes.
611      * @param networkTerminationPoint TerminationPoint1
612      * @param atozMinFrequency BigDecimal
613      * @param atozMaxFrequency BigDecimal
614      * @param used boolean true if min and max frequencies are used, false otherwise.
615      * @return RxTtpAttributes with frequency map updated
616      */
617     private RxTtpAttributes updateRxTtpAttributes(TerminationPoint1 networkTerminationPoint, Decimal64 atozMinFrequency,
618             Decimal64 atozMaxFrequency, boolean used) {
619         LOG.debug("Update rx attributes for termination point {}, min frequency {}, max frequency {}, used {}",
620                 networkTerminationPoint, atozMinFrequency, atozMaxFrequency, used);
621         RxTtpAttributesBuilder rxTtpAttributesBuilder =
622             networkTerminationPoint == null
623                 ? new RxTtpAttributesBuilder()
624                 : new RxTtpAttributesBuilder(networkTerminationPoint.getRxTtpAttributes());
625         return rxTtpAttributesBuilder
626             .setAvailFreqMaps(
627                 updateFreqMaps(
628                     atozMinFrequency, atozMaxFrequency,
629                     rxTtpAttributesBuilder.getAvailFreqMaps(),
630                     used))
631             .build();
632     }
633
634     /**
635      * Update freqMaps for txtp attributes.
636      * @param networkTerminationPoint TerminationPoint1
637      * @param atozMinFrequency BigDecimal
638      * @param atozMaxFrequency BigDecimal
639      * @param used boolean true if min and max frequencies are used, false otherwise.
640      * @return TxTtpAttributes with frequency map updated
641      */
642     private TxTtpAttributes updateTxTtpAttributes(TerminationPoint1 networkTerminationPoint, Decimal64 atozMinFrequency,
643             Decimal64 atozMaxFrequency, boolean used) {
644         LOG.debug("Update tx attributes for termination point {}, min frequency {}, max frequency {}, used {}",
645                 networkTerminationPoint, atozMinFrequency, atozMaxFrequency, used);
646         TxTtpAttributesBuilder txTtpAttributesBuilder =
647             networkTerminationPoint == null
648                 ? new TxTtpAttributesBuilder()
649                 : new TxTtpAttributesBuilder(networkTerminationPoint.getTxTtpAttributes());
650         return txTtpAttributesBuilder
651             .setAvailFreqMaps(
652                 updateFreqMaps(
653                     atozMinFrequency, atozMaxFrequency,
654                     txTtpAttributesBuilder.getAvailFreqMaps(),
655                     used))
656             .build();
657     }
658
659     /**
660      * Update freqMaps for srg attributes of srgAttributes.
661      * @param srgAttributes SrgAttributes
662      * @param atozMinFrequency BigDecimal
663      * @param atozMaxFrequency BigDecimal
664      * @param used boolean true if min and max frequencies are used, false otherwise.
665      * @return SrgAttributes with frequency map updated
666      */
667     private SrgAttributes updateSrgAttributes(SrgAttributes srgAttributes, Decimal64 atozMinFrequency,
668             Decimal64 atozMaxFrequency, boolean used) {
669         SrgAttributesBuilder srgAttributesBuilder =
670             srgAttributes == null
671                 ? new SrgAttributesBuilder()
672                 : new SrgAttributesBuilder(srgAttributes);
673         return srgAttributesBuilder
674             .setAvailFreqMaps(
675                 updateFreqMaps(
676                     atozMinFrequency, atozMaxFrequency,
677                     srgAttributesBuilder.getAvailFreqMaps(),
678                     used))
679             .build();
680     }
681
682     /**
683      * Update freqMaps for degree attributes of degreeAttributes.
684      * @param degreeAttributes DegreeAttributes
685      * @param atozMinFrequency BigDecimal
686      * @param atozMaxFrequency BigDecimal
687      * @param used boolean true if min and max frequencies are used, false otherwise.
688      * @return DegreeAttributes with frequency map updated
689      */
690     private DegreeAttributes updateDegreeAttributes(DegreeAttributes degreeAttributes, Decimal64 atozMinFrequency,
691             Decimal64 atozMaxFrequency, boolean used) {
692         DegreeAttributesBuilder degreeAttributesBuilder =
693             degreeAttributes == null
694                 ? new DegreeAttributesBuilder()
695                 : new DegreeAttributesBuilder(degreeAttributes);
696         return degreeAttributesBuilder
697             .setAvailFreqMaps(
698                 updateFreqMaps(
699                     atozMinFrequency, atozMaxFrequency,
700                     degreeAttributesBuilder.getAvailFreqMaps(),
701                     used))
702             .build();
703     }
704
705     /**
706      * Update availFreqMapsMap for min and max frequencies for cband AvailFreqMaps.
707      * @param atozMinFrequency BigDecimal
708      * @param atozMaxFrequency BigDecimal
709      * @param availFreqMapsMap Map
710      * @param used boolean
711      * @return updated Update availFreqMapsMap for min and max frequencies for cband AvailFreqMaps.
712      */
713     private Map<AvailFreqMapsKey, AvailFreqMaps> updateFreqMaps(Decimal64 atozMinFrequency, Decimal64 atozMaxFrequency,
714             Map<AvailFreqMapsKey, AvailFreqMaps> availFreqMapsMap, boolean used) {
715         int beginIndex = GridUtils.getIndexFromFrequency(atozMinFrequency);
716         int endIndex = GridUtils.getIndexFromFrequency(atozMaxFrequency);
717         if (availFreqMapsMap == null) {
718             availFreqMapsMap = GridUtils.initFreqMaps4FixedGrid2Available();
719         }
720         AvailFreqMaps availFreqMaps = availFreqMapsMap.get(availFreqMapKey);
721         if (availFreqMaps == null || availFreqMaps.getFreqMap() == null) {
722             return availFreqMapsMap;
723         }
724         BitSet bitSetFreq = BitSet.valueOf(availFreqMaps.getFreqMap());
725         LOG.debug(
726              "Update frequency map from index {}, to index {}, min frequency {}, max frequency {}, available {} {}",
727              beginIndex, endIndex, atozMinFrequency, atozMaxFrequency, !used, bitSetFreq);
728         //if used = true then bit must be set to false to indicate the slot is no more available
729         bitSetFreq.set(beginIndex, endIndex, !used);
730         LOG.debug(
731             "Updated frequency map from index {}, to index {}, min frequency {}, max frequency {}, available {} {}",
732             beginIndex, endIndex, atozMinFrequency, atozMaxFrequency, !used, bitSetFreq);
733         AvailFreqMaps updatedAvailFreqMaps = new AvailFreqMapsBuilder(availFreqMaps)
734                 .setFreqMap(Arrays.copyOf(bitSetFreq.toByteArray(), GridConstant.NB_OCTECTS))
735                 .build();
736         return new HashMap<>(Map.of(availFreqMaps.key(), updatedAvailFreqMaps));
737     }
738 }