f0d2cb8d3ff60b83e9e5661808641272cfa2175f
[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.math.BigDecimal;
11 import java.util.Arrays;
12 import java.util.BitSet;
13 import java.util.Collection;
14 import java.util.HashMap;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Objects;
18 import java.util.Optional;
19 import java.util.concurrent.ExecutionException;
20 import java.util.concurrent.TimeUnit;
21 import java.util.concurrent.TimeoutException;
22 import java.util.stream.Collectors;
23 import org.opendaylight.mdsal.binding.api.DataBroker;
24 import org.opendaylight.mdsal.binding.api.ReadTransaction;
25 import org.opendaylight.mdsal.binding.api.WriteTransaction;
26 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
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.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             BigDecimal atozMinFrequency = atoZDirection.getAToZMinFrequency().getValue();
102             BigDecimal 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             BigDecimal ztoaMinFrequency = ztoADirection.getZToAMinFrequency().getValue();
121             BigDecimal 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 minFrequency BigDecimal
203      * @param maxFrequency 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(BigDecimal minFrequency, BigDecimal maxFrequency,
208             List<String> nodeIds, boolean used) {
209         updateFreqMaps4Nodes(nodeIds, minFrequency, maxFrequency, 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 minFrequency BigDecimal
281      * @param maxFrequency 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(BigDecimal minFrequency, BigDecimal maxFrequency, 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                 minFrequency, maxFrequency, 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                             minFrequency,maxFrequency,used));
316                     break;
317                 case DEGREERXTTP:
318                     networkTerminationPointBuilder.setRxTtpAttributes(updateRxTtpAttributes(networkTerminationPoint,
319                             minFrequency,maxFrequency,used));
320                     break;
321                 case DEGREETXCTP:
322                 case DEGREERXCTP:
323                 case DEGREETXRXCTP:
324                     networkTerminationPointBuilder.setCtpAttributes(updateCtpAttributes(networkTerminationPoint,
325                             minFrequency,maxFrequency,used));
326                     break;
327                 case SRGTXCP:
328                 case SRGRXCP:
329                 case SRGTXRXCP:
330                     networkTerminationPointBuilder.setCpAttributes(updateCpAttributes(networkTerminationPoint,
331                             minFrequency,maxFrequency,used));
332                     break;
333                 case SRGTXRXPP:
334                 case SRGRXPP:
335                 case SRGTXPP:
336                     networkTerminationPointBuilder.setPpAttributes(updatePpAttributes(networkTerminationPoint,
337                             minFrequency,maxFrequency,used));
338                     break;
339                 case XPONDERNETWORK:
340                     networkTerminationPointBuilder.setXpdrNetworkAttributes(
341                             updateXpdrNetworkAttributes(networkTerminationPoint,
342                                     minFrequency, maxFrequency, rate, modulationFormat, used)).build();
343                     break;
344                 case XPONDERCLIENT:
345                     break;
346                 case XPONDERPORT:
347                     networkTerminationPointBuilder.setXpdrPortAttributes(
348                             updateXpdrPortAttributes(networkTerminationPoint,
349                                     minFrequency, maxFrequency, 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                 minFrequency, maxFrequency, used, strTpIdsList, e);
365         } catch (InterruptedException e) {
366             LOG.error("Frequencies update (min frequency {}, max frequency {}, used {} for TPs {} was interrupted",
367                     minFrequency, maxFrequency, 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 minFrequency BigDecimal
377      * @param maxFrequency BigDecimal
378      * @param used boolean true if min and max frequencies are used, false otherwise.
379      */
380     private void updateFreqMaps4Nodes(List<String> nodeIds, BigDecimal minFrequency, BigDecimal maxFrequency,
381             boolean used) {
382         String strNodesList = String.join(", ", nodeIds);
383         LOG.debug("Update frequencies for nodes {}, min frequency {}, max frequency {}, used {}",
384                 strNodesList, minFrequency, maxFrequency, 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(), minFrequency,
402                                     maxFrequency, used));
403                     break;
404                 case SRG:
405                     networkNodeBuilder.setSrgAttributes(
406                             updateSrgAttributes(networkNode.getSrgAttributes(), minFrequency, maxFrequency, 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 {}", minFrequency, maxFrequency,
419                     strNodesList, e);
420         } catch (InterruptedException e) {
421             LOG.error("Update of frequencies {} {} for nodes {} was interrupted", minFrequency, maxFrequency,
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 minFrequency BigDecimal
483      * @param maxFrequency 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             BigDecimal minFrequency, BigDecimal maxFrequency, Uint32 rate, ModulationFormat modulationFormat,
491             boolean used) {
492         LOG.debug("Update xpdr node attributes for termination point {}, min frequency {}, max frequency {}, used {}",
493                 networkTerminationPoint, minFrequency, maxFrequency, 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.getCentralFrequency(minFrequency, maxFrequency));
504         }
505         return xpdrPortAttributesBuilder.setWavelength(waveLengthBuilder.build()).build();
506     }
507
508     /**
509      * Update Wavelength for xpdr network attributes.
510      * @param networkTerminationPoint TerminationPoint1
511      * @param minFrequency BigDecimal
512      * @param maxFrequency BigDecimal
513      * @param rate Uint32
514      * @param modulationFormat ModulationFormat
515      * @param used boolean true if min and max frequencies are used, false otherwise.
516      * @return XpdrNetworkAttributes with Wavelength updated
517      */
518     private XpdrNetworkAttributes updateXpdrNetworkAttributes(TerminationPoint1 networkTerminationPoint,
519             BigDecimal minFrequency, BigDecimal maxFrequency, Uint32 rate, ModulationFormat modulationFormat,
520             boolean used) {
521         LOG.debug("Update xpdr node attributes for termination point {}, min frequency {}, max frequency {}, used {}",
522                 networkTerminationPoint, minFrequency, maxFrequency, used);
523         XpdrNetworkAttributesBuilder xpdrNetworkAttributesBuilder;
524         if (networkTerminationPoint != null) {
525             xpdrNetworkAttributesBuilder = new XpdrNetworkAttributesBuilder(
526                     networkTerminationPoint.getXpdrNetworkAttributes());
527         } else {
528             xpdrNetworkAttributesBuilder = new XpdrNetworkAttributesBuilder();
529         }
530         WavelengthBuilder waveLengthBuilder = new WavelengthBuilder();
531         if (used) {
532             waveLengthBuilder.setWidth(GridUtils.getWidthFromRateAndModulationFormat(rate, modulationFormat))
533                     .setFrequency(GridUtils.getCentralFrequency(minFrequency, maxFrequency));
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 minFrequency BigDecimal
545      * @param maxFrequency 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, BigDecimal minFrequency,
550             BigDecimal maxFrequency, boolean used) {
551         LOG.debug("Update pp attributes for termination point {}, min frequency {}, max frequency {}, used {}",
552                 networkTerminationPoint, minFrequency, maxFrequency, 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.setAvailFreqMaps(updateFreqMaps(minFrequency, maxFrequency, availFreqMapsMap, used))
561                 .build();
562     }
563
564     /**
565      * Update freqMaps for cp attributes.
566      * @param networkTerminationPoint TerminationPoint1
567      * @param minFrequency BigDecimal
568      * @param maxFrequency 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, BigDecimal minFrequency,
573             BigDecimal maxFrequency, boolean used) {
574         LOG.debug("Update cp attributes for termination point {}, min frequency {}, max frequency {}, used {}",
575                 networkTerminationPoint, minFrequency, maxFrequency, 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.setAvailFreqMaps(updateFreqMaps(minFrequency, maxFrequency, availFreqMapsMap, used))
584                 .build();
585     }
586
587     /**
588      * Update freqMaps for ctp attributes.
589      * @param networkTerminationPoint TerminationPoint1
590      * @param minFrequency BigDecimal
591      * @param maxFrequency BigDecimal
592      * @param used boolean true if min and max frequencies are used, false otherwise.
593      * @return CtpAttributes with frequency map updated
594      */
595     private CtpAttributes updateCtpAttributes(TerminationPoint1 networkTerminationPoint, BigDecimal minFrequency,
596             BigDecimal maxFrequency, boolean used) {
597         LOG.debug("Update ctp attributes for termination point {}, min frequency {}, max frequency {}, used {}",
598                 networkTerminationPoint, minFrequency, maxFrequency, used);
599         CtpAttributesBuilder ctpAttributesBuilder;
600         if (networkTerminationPoint != null) {
601             ctpAttributesBuilder = new CtpAttributesBuilder(networkTerminationPoint.getCtpAttributes());
602         } else {
603             ctpAttributesBuilder = new CtpAttributesBuilder();
604         }
605         Map<AvailFreqMapsKey, AvailFreqMaps> availFreqMapsMap = ctpAttributesBuilder.getAvailFreqMaps();
606         return ctpAttributesBuilder.setAvailFreqMaps(updateFreqMaps(minFrequency, maxFrequency, availFreqMapsMap, used))
607                 .build();
608     }
609
610     /**
611      * Update freqMaps for rxtp attributes.
612      * @param networkTerminationPoint TerminationPoint1
613      * @param minFrequency BigDecimal
614      * @param maxFrequency BigDecimal
615      * @param used boolean true if min and max frequencies are used, false otherwise.
616      * @return RxTtpAttributes with frequency map updated
617      */
618     private RxTtpAttributes updateRxTtpAttributes(TerminationPoint1 networkTerminationPoint, BigDecimal minFrequency,
619             BigDecimal maxFrequency, boolean used) {
620         LOG.debug("Update rx attributes for termination point {}, min frequency {}, max frequency {}, used {}",
621                 networkTerminationPoint, minFrequency, maxFrequency, used);
622         RxTtpAttributesBuilder rxTtpAttributesBuilder;
623         if (networkTerminationPoint != null) {
624             rxTtpAttributesBuilder = new RxTtpAttributesBuilder(networkTerminationPoint.getRxTtpAttributes());
625         } else {
626             rxTtpAttributesBuilder = new RxTtpAttributesBuilder();
627         }
628         Map<AvailFreqMapsKey, AvailFreqMaps> availFreqMapsMap = rxTtpAttributesBuilder.getAvailFreqMaps();
629         return rxTtpAttributesBuilder
630                 .setAvailFreqMaps(updateFreqMaps(minFrequency, maxFrequency, availFreqMapsMap, used)).build();
631     }
632
633     /**
634      * Update freqMaps for txtp attributes.
635      * @param networkTerminationPoint TerminationPoint1
636      * @param minFrequency BigDecimal
637      * @param maxFrequency BigDecimal
638      * @param used boolean true if min and max frequencies are used, false otherwise.
639      * @return TxTtpAttributes with frequency map updated
640      */
641     private TxTtpAttributes updateTxTtpAttributes(TerminationPoint1 networkTerminationPoint, BigDecimal minFrequency,
642             BigDecimal maxFrequency, boolean used) {
643         LOG.debug("Update tx attributes for termination point {}, min frequency {}, max frequency {}, used {}",
644                 networkTerminationPoint, minFrequency, maxFrequency, used);
645         TxTtpAttributesBuilder txTtpAttributesBuilder;
646         if (networkTerminationPoint != null) {
647             txTtpAttributesBuilder = new TxTtpAttributesBuilder(networkTerminationPoint.getTxTtpAttributes());
648         } else {
649             txTtpAttributesBuilder = new TxTtpAttributesBuilder();
650         }
651         Map<AvailFreqMapsKey, AvailFreqMaps> availFreqMapsMap = txTtpAttributesBuilder.getAvailFreqMaps();
652         return txTtpAttributesBuilder
653                 .setAvailFreqMaps(updateFreqMaps(minFrequency, maxFrequency, availFreqMapsMap, used)).build();
654     }
655
656     /**
657      * Update freqMaps for srg attributes of srgAttributes.
658      * @param srgAttributes SrgAttributes
659      * @param minFrequency BigDecimal
660      * @param maxFrequency BigDecimal
661      * @param used boolean true if min and max frequencies are used, false otherwise.
662      * @return SrgAttributes with frequency map updated
663      */
664     private SrgAttributes updateSrgAttributes(SrgAttributes srgAttributes, BigDecimal minFrequency,
665             BigDecimal maxFrequency, boolean used) {
666         Map<AvailFreqMapsKey, AvailFreqMaps> availFreqMapsMap;
667         SrgAttributesBuilder srgAttributesBuilder;
668         if (srgAttributes == null) {
669             srgAttributesBuilder = new SrgAttributesBuilder();
670         } else {
671             srgAttributesBuilder = new SrgAttributesBuilder(srgAttributes);
672         }
673         availFreqMapsMap = srgAttributesBuilder.getAvailFreqMaps();
674         return srgAttributesBuilder.setAvailFreqMaps(updateFreqMaps(minFrequency, maxFrequency, availFreqMapsMap, used))
675                 .build();
676     }
677
678     /**
679      * Update freqMaps for degree attributes of degreeAttributes.
680      * @param degreeAttributes DegreeAttributes
681      * @param minFrequency BigDecimal
682      * @param maxFrequency BigDecimal
683      * @param used boolean true if min and max frequencies are used, false otherwise.
684      * @return DegreeAttributes with frequency map updated
685      */
686     private DegreeAttributes updateDegreeAttributes(DegreeAttributes degreeAttributes, BigDecimal minFrequency,
687             BigDecimal maxFrequency, boolean used) {
688         Map<AvailFreqMapsKey, AvailFreqMaps> availFreqMapsMap;
689         DegreeAttributesBuilder degreeAttributesBuilder;
690         if (degreeAttributes == null) {
691             degreeAttributesBuilder = new DegreeAttributesBuilder();
692         } else {
693             degreeAttributesBuilder = new DegreeAttributesBuilder(degreeAttributes);
694         }
695         availFreqMapsMap = degreeAttributesBuilder.getAvailFreqMaps();
696         return degreeAttributesBuilder
697                 .setAvailFreqMaps(updateFreqMaps(minFrequency, maxFrequency, availFreqMapsMap, used)).build();
698     }
699
700     /**
701      * Update availFreqMapsMap for min and max frequencies for cband AvailFreqMaps.
702      * @param minFrequency BigDecimal
703      * @param maxFrequency BigDecimal
704      * @param availFreqMapsMap Map
705      * @param used boolean
706      * @return updated Update availFreqMapsMap for min and max frequencies for cband AvailFreqMaps.
707      */
708     private Map<AvailFreqMapsKey, AvailFreqMaps> updateFreqMaps(BigDecimal minFrequency, BigDecimal maxFrequency,
709             Map<AvailFreqMapsKey, AvailFreqMaps> availFreqMapsMap, boolean used) {
710         int beginIndex = GridUtils.getIndexFromFrequency(minFrequency);
711         int endIndex = GridUtils.getIndexFromFrequency(maxFrequency);
712         if (availFreqMapsMap == null) {
713             availFreqMapsMap = GridUtils.initFreqMaps4FixedGrid2Available();
714         }
715         AvailFreqMaps availFreqMaps = availFreqMapsMap.get(availFreqMapKey);
716         if (availFreqMaps != null && availFreqMaps.getFreqMap() != null) {
717             BitSet bitSetFreq = BitSet.valueOf(availFreqMaps.getFreqMap());
718             LOG.debug(
719                  "Update frequency map from index {}, to index {}, min frequency {}, max frequency {}, available {} {}",
720                  beginIndex, endIndex, minFrequency, maxFrequency, !used, bitSetFreq);
721             //if used = true then bit must be set to false to indicate the slot is no more available
722             bitSetFreq.set(beginIndex, endIndex, !used);
723             LOG.debug(
724                 "Updated frequency map from index {}, to index {}, min frequency {}, max frequency {}, available {} {}",
725                 beginIndex, endIndex, minFrequency, maxFrequency, !used, bitSetFreq);
726             Map<AvailFreqMapsKey, AvailFreqMaps> updatedFreqMaps = new HashMap<>();
727             byte[] frequenciesByteArray = bitSetFreq.toByteArray();
728             AvailFreqMaps updatedAvailFreqMaps = new AvailFreqMapsBuilder(availFreqMaps)
729                     .setFreqMap(Arrays.copyOf(frequenciesByteArray,GridConstant.NB_OCTECTS))
730                     .build();
731             updatedFreqMaps.put(availFreqMaps.key(), updatedAvailFreqMaps);
732             return updatedFreqMaps;
733         }
734         return availFreqMapsMap;
735     }
736 }