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