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