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