611263d68a3f43e490abc0af1ab034a9146faa65
[transportpce.git] / pce / src / main / java / org / opendaylight / transportpce / pce / networkanalyzer / PceOpticalNode.java
1 /*
2  * Copyright © 2020 Orange, Inc. 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
9 package org.opendaylight.transportpce.pce.networkanalyzer;
10
11 import java.math.BigDecimal;
12 import java.util.ArrayList;
13 import java.util.Arrays;
14 import java.util.BitSet;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Optional;
19 import java.util.TreeMap;
20 import org.opendaylight.transportpce.common.StringConstants;
21 import org.opendaylight.transportpce.common.fixedflex.GridConstant;
22 import org.opendaylight.transportpce.common.mapping.PortMapping;
23 import org.opendaylight.transportpce.pce.SortPortsByName;
24 import org.opendaylight.transportpce.pce.networkanalyzer.port.Preference;
25 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev240205.path.computation.reroute.request.input.Endpoints;
26 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev231221.mapping.Mapping;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev230526.TerminationPoint1;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev230526.Node1;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev230526.networks.network.node.termination.point.XpdrNetworkAttributes;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev230526.OpenroadmNodeType;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev230526.OpenroadmTpType;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev230526.available.freq.map.AvailFreqMapsKey;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev230526.IfOCH;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev230526.IfOCHOTU4ODU4;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev230526.IfOtsiOtsigroup;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev230526.SupportedIfCapability;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.format.rev191129.ServiceFormat;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.xponder.rev230526.xpdr.mode.attributes.supported.operational.modes.OperationalMode;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.xponder.rev230526.xpdr.mode.attributes.supported.operational.modes.OperationalModeKey;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node;
44 import org.opendaylight.yangtools.yang.common.Uint16;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 public class PceOpticalNode implements PceNode {
49     private static final Logger LOG = LoggerFactory.getLogger(PceOpticalNode.class);
50
51     private boolean valid = true;
52
53     private Node node;
54     private NodeId nodeId;
55     private String deviceNodeId;
56     private OpenroadmNodeType nodeType;
57     private AdminStates adminStates;
58     private State state;
59     private String serviceType;
60     private PortMapping portMapping;
61
62     private Map<String, OpenroadmTpType> availableSrgPp = new TreeMap<>();
63     private Map<String, OpenroadmTpType> availableSrgCp = new TreeMap<>();
64     private List<String> usedXpndrNWTps = new ArrayList<>();
65     private List<PceLink> outgoingLinks = new ArrayList<>();
66     private Map<String, String> clientPerNwTp = new HashMap<>();
67     private final AvailFreqMapsKey freqMapKey = new AvailFreqMapsKey(GridConstant.C_BAND);
68     private BitSet frequenciesBitSet;
69     private String version;
70     private BigDecimal slotWidthGranularity;
71     private BigDecimal centralFreqGranularity;
72     private Endpoints endpoints;
73
74     public PceOpticalNode(String deviceNodeId, String serviceType, PortMapping portMapping, Node node,
75         OpenroadmNodeType nodeType, String version, BigDecimal slotWidthGranularity,
76                           BigDecimal centralFreqGranularity) {
77
78         if (deviceNodeId != null
79                 && serviceType != null
80                 && portMapping != null
81                 && node != null
82                 && node.getNodeId() != null
83                 && nodeType != null
84                 && version != null
85                 && slotWidthGranularity != null) {
86             this.deviceNodeId = deviceNodeId;
87             this.serviceType = serviceType;
88             this.portMapping = portMapping;
89             this.node = node;
90             this.nodeId = node.getNodeId();
91             this.nodeType = nodeType;
92             this.version = version;
93             this.slotWidthGranularity = slotWidthGranularity;
94             this.centralFreqGranularity = centralFreqGranularity;
95             this.adminStates = node.augmentation(org.opendaylight.yang.gen.v1.http
96                     .org.openroadm.common.network.rev230526.Node1.class).getAdministrativeState();
97             this.state = node.augmentation(org.opendaylight.yang.gen.v1.http
98                 .org.openroadm.common.network.rev230526.Node1.class).getOperationalState();
99         } else {
100             LOG.error("PceNode {} : one of parameters is not populated : nodeId, node type, slot width granularity",
101                 deviceNodeId);
102             this.valid = false;
103         }
104     }
105
106     public void initSrgTps(Preference portPreference) {
107         this.availableSrgPp.clear();
108         this.availableSrgCp.clear();
109         if (!isValid()) {
110             return;
111         }
112         LOG.debug("initSrgTpList: getting SRG tps from ROADM node {}", this.nodeId);
113         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1 nodeTp =
114                 this.node.augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
115                     .ietf.network.topology.rev180226.Node1.class);
116         List<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network
117             .node.TerminationPoint> allTps = new ArrayList<>(nodeTp.nonnullTerminationPoint().values());
118         if (allTps.isEmpty()) {
119             LOG.error("initSrgTpList: ROADM TerminationPoint list is empty for node {}", this);
120             this.valid = false;
121             return;
122         }
123         for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network
124             .node.TerminationPoint tp : allTps) {
125             TerminationPoint1 cntp1 = tp.augmentation(TerminationPoint1.class);
126             org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev230526.TerminationPoint1 nttp1 = tp
127                 .augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev230526
128                         .TerminationPoint1.class);
129             OpenroadmTpType type = cntp1.getTpType();
130             LOG.debug("type = {} for tp {}", type.getName(), tp);
131
132             switch (type) {
133                 case SRGTXRXCP:
134                 case SRGRXCP:
135                 case SRGTXCP:
136                     if (State.InService.equals(cntp1.getOperationalState())) {
137                         LOG.debug("initSrgTpList: adding SRG-CP tp = {} ", tp.getTpId().getValue());
138                         this.availableSrgCp.put(tp.getTpId().getValue(), cntp1.getTpType());
139                     }
140                     break;
141                 case SRGRXPP:
142                 case SRGTXPP:
143                 case SRGTXRXPP:
144                     LOG.debug("initSrgTpList: SRG-PP tp = {} found", tp.getTpId().getValue());
145                     if (!portPreference.isPreferredPort(nodeId.getValue(), tp.getTpId().getValue())) {
146                         LOG.warn("initSrgTpList: SRG-PP tp = {} is rejected by the client", tp.getTpId().getValue());
147                         break;
148                     }
149                     if (isTerminationPointAvailable(nttp1)) {
150                         LOG.debug("initSrgTpList: adding SRG-PP tp '{}'", tp.getTpId().getValue());
151                         this.availableSrgPp.put(tp.getTpId().getValue(), cntp1.getTpType());
152                         if (State.InService.equals(cntp1.getOperationalState())) {
153                             LOG.debug("initSrgTpList: adding SRG-PP tp '{}'", tp.getTpId().getValue());
154                             this.availableSrgPp.put(tp.getTpId().getValue(), cntp1.getTpType());
155                         }
156                     } else {
157                         LOG.warn("initSrgTpList: SRG-PP tp = {} found is busy !!", tp.getTpId().getValue());
158                     }
159                     break;
160                 default:
161                     break;
162             }
163         }
164         if (this.availableSrgPp.isEmpty() || this.availableSrgCp.isEmpty()) {
165             LOG.error("initSrgTpList: ROADM SRG TerminationPoint list is empty for node {}", this);
166             this.valid = false;
167             return;
168         }
169         LOG.debug("initSrgTpList: availableSrgPp size = {} && availableSrgCp size = {} in {}",
170             this.availableSrgPp.size(), this.availableSrgCp.size(), this);
171     }
172
173     private boolean isTerminationPointAvailable(
174             org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev230526.TerminationPoint1 nttp1) {
175         byte[] availableByteArray = new byte[GridConstant.NB_OCTECTS];
176         Arrays.fill(availableByteArray, (byte) GridConstant.AVAILABLE_SLOT_VALUE);
177         return nttp1 == null || nttp1.getPpAttributes() == null
178                 || nttp1.getPpAttributes().getAvailFreqMaps() == null
179                 || !nttp1.getPpAttributes().getAvailFreqMaps().containsKey(freqMapKey)
180                 || nttp1.getPpAttributes().getAvailFreqMaps().get(freqMapKey).getFreqMap() == null
181                 || Arrays.equals(nttp1.getPpAttributes().getAvailFreqMaps().get(freqMapKey).getFreqMap(),
182                         availableByteArray);
183     }
184
185     private boolean isTpWithGoodCapabilities(
186         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node
187         .TerminationPoint tp) {
188         Mapping mapping = this.portMapping.getMapping(deviceNodeId, tp.getTpId().getValue());
189         if (mapping == null || mapping.getSupportedInterfaceCapability() == null) {
190             return true;
191         }
192         switch (this.serviceType) {
193             case "400GE":
194                 for (SupportedIfCapability ifCap : mapping.getSupportedInterfaceCapability()) {
195                     if (ifCap.equals(IfOtsiOtsigroup.VALUE)) {
196                         return true;
197                     }
198                 }
199                 return false;
200             case "100GE":
201                 return mapping.getSupportedInterfaceCapability().contains(IfOCH.VALUE)
202                         || mapping.getSupportedInterfaceCapability().contains(IfOCHOTU4ODU4.VALUE);
203             default:
204                 return true;
205         }
206     }
207
208     public void initFrequenciesBitSet() {
209         if (!isValid()) {
210             return;
211         }
212         Node1 node1 = this.node.augmentation(Node1.class);
213         org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev230526.Node1 node11 =
214                 this.node.augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev230526.Node1
215                         .class);
216         switch (this.nodeType) {
217             case SRG :
218                 if (!State.InService.equals(node11.getOperationalState())) {
219                     this.valid = false;
220                     LOG.error("initWLlist: SRG node {} is OOS/degraded", this);
221                     return;
222                 }
223                 if (!node1.getSrgAttributes().nonnullAvailFreqMaps().containsKey(freqMapKey)) {
224                     LOG.error("initFrequenciesBitSet: SRG no cband available freq maps for node  {}", this);
225                     this.valid = false;
226                     return;
227                 }
228                 this.frequenciesBitSet = BitSet.valueOf(node1.getSrgAttributes()
229                         .nonnullAvailFreqMaps().get(freqMapKey).getFreqMap());
230                 break;
231             case DEGREE :
232                 if (!State.InService.equals(node11.getOperationalState())) {
233                     this.valid = false;
234                     LOG.error("initWLlist: Degree node {} is OOS/degraded", this);
235                     return;
236                 }
237                 if (!node1.getDegreeAttributes().nonnullAvailFreqMaps().containsKey(freqMapKey)) {
238                     LOG.error("initFrequenciesBitSet: DEG no cband available freq maps for node  {}", this);
239                     this.valid = false;
240                     return;
241                 }
242                 this.frequenciesBitSet = BitSet.valueOf(node1.getDegreeAttributes()
243                         .nonnullAvailFreqMaps().get(freqMapKey).getFreqMap());
244                 break;
245             case XPONDER :
246                 // at init all bits are set to false (unavailable)
247                 this.frequenciesBitSet = new BitSet(GridConstant.EFFECTIVE_BITS);
248                 //set all bits to true (available)
249                 this.frequenciesBitSet.set(0, GridConstant.EFFECTIVE_BITS);
250                 if (!State.InService.equals(node11.getOperationalState())) {
251                     this.valid = false;
252                     LOG.error("initWLlist: XPDR node {} is OOS/degraded", this);
253                 }
254                 break;
255             default:
256                 LOG.error("initFrequenciesBitSet: unsupported node type {} in node {}", this.nodeType, this);
257                 break;
258         }
259     }
260
261     public void initXndrTps(ServiceFormat serviceFormat) {
262         LOG.debug("PceNod: initXndrTps for node : {}", this.nodeId);
263         if (!isValid()) {
264             return;
265         }
266         this.valid = false;
267         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1 nodeTp =
268                 this.node.augmentation(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
269                     .ietf.network.topology.rev180226.Node1.class);
270         List<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network
271             .node.TerminationPoint> allTps = new ArrayList<>(nodeTp.nonnullTerminationPoint().values());
272         if (allTps.isEmpty()) {
273             LOG.error("initXndrTps: XPONDER TerminationPoint list is empty for node {}", this);
274             return;
275         }
276         for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network
277                 .node.TerminationPoint tp : allTps) {
278             TerminationPoint1 cntp1 = tp.augmentation(TerminationPoint1.class);
279             if (cntp1 == null) {
280                 LOG.error("initXndrTps: {} - {} has no tp type", this.nodeId, tp.getTpId().toString());
281                 continue;
282             }
283             if (cntp1.getTpType() != OpenroadmTpType.XPONDERNETWORK) {
284                 LOG.debug("initXndrTps: {} is not an Xponder network port", cntp1.getTpType().getName());
285                 continue;
286             }
287             if (!isTpWithGoodCapabilities(tp)) {
288                 LOG.warn("initXndrTps: {} network port has not correct if-capabilities", tp.getTpId().getValue());
289                 continue;
290             }
291             if (!State.InService.equals(cntp1.getOperationalState())) {
292                 LOG.warn("initXndrTps: XPONDER tp = {} is OOS/degraded", tp.getTpId().getValue());
293                 continue;
294             }
295             if (endpoints == null
296                     || (!endpoints.getAEndTp().equals(tp.getTpId().getValue())
297                         && !endpoints.getZEndTp().equals(tp.getTpId().getValue()))) {
298                 org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev230526.TerminationPoint1 nttp1 =
299                         tp.augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev230526
300                                 .TerminationPoint1.class);
301                 if (nttp1 != null && nttp1.getXpdrNetworkAttributes().getWavelength() != null) {
302                     this.usedXpndrNWTps.add(tp.getTpId().getValue());
303                     LOG.debug("initXndrTps: XPONDER tp = {} is used", tp.getTpId().getValue());
304                     continue;
305                 }
306             }
307             // find Client of this network TP
308             if (cntp1.getAssociatedConnectionMapTp() != null) {
309                 String client = cntp1.getAssociatedConnectionMapTp().iterator().next().getValue();
310                 if (client != null) {
311                     this.clientPerNwTp.put(tp.getTpId().getValue(), client);
312                     this.valid = true;
313                 } else {
314                     LOG.error("Service Format {} not managed yet", serviceFormat.getName());
315                 }
316             } else {
317                 this.valid = true;
318             }
319         }
320         if (!isValid()) {
321             LOG.error("initXndrTps: XPONDER doesn't have available wavelengths for node  {}", this);
322         }
323     }
324
325     @Override
326     public String getRdmSrgClient(String tp, String direction) {
327         LOG.debug("getRdmSrgClient: Getting PP client for tp '{}' on node : {}", tp, this.nodeId);
328         OpenroadmTpType srgType = null;
329         OpenroadmTpType cpType = this.availableSrgCp.get(tp);
330         if (cpType == null) {
331             LOG.error("getRdmSrgClient: tp {} not existed in SRG CPterminationPoint list", tp);
332             return null;
333         }
334         switch (cpType) {
335             case SRGTXRXCP:
336                 LOG.debug("getRdmSrgClient: Getting BI Directional PP port ...");
337                 // Take the first-element in the available PP key set
338                 if (availableSrgPp.entrySet().iterator().next().getKey()
339                         // and check if the port is bidirectional
340                         .contains("TXRX")) {
341                     srgType = OpenroadmTpType.SRGTXRXPP;
342                 } else if (direction.equalsIgnoreCase("aToz")) {
343                     srgType = OpenroadmTpType.SRGRXPP;
344                 } else {
345                     srgType = OpenroadmTpType.SRGTXPP;
346                 }
347                 break;
348             case SRGTXCP:
349                 LOG.debug("getRdmSrgClient: Getting UNI Rx PP port ...");
350                 srgType = OpenroadmTpType.SRGRXPP;
351                 break;
352             case SRGRXCP:
353                 LOG.debug("getRdmSrgClient: Getting UNI Tx PP port ...");
354                 srgType = OpenroadmTpType.SRGTXPP;
355                 break;
356             default:
357                 break;
358         }
359         LOG.debug("getRdmSrgClient:  Getting client PP for CP '{}'", tp);
360         if (this.availableSrgPp.isEmpty()) {
361             LOG.error("getRdmSrgClient: SRG TerminationPoint PP list is not available for node {}", this);
362             return null;
363         }
364         final OpenroadmTpType openType = srgType;
365         Optional<String> client = this.availableSrgPp.entrySet()
366                 .stream().filter(pp -> pp.getValue().getName().equals(openType.getName()))
367                 .map(Map.Entry::getKey).min(new SortPortsByName());
368         if (client.isEmpty()) {
369             LOG.error("getRdmSrgClient: ROADM {} doesn't have PP Client for CP {}", this, tp);
370             return null;
371         }
372         LOG.debug("getRdmSrgClient: client PP {} for CP {} found !", client, tp);
373         return client.orElseThrow();
374     }
375
376     @Override
377     public String getOperationalMode() {
378         Node1 node1 = this.node.augmentation(Node1.class);
379         if (node1 == null) {
380             LOG.warn("No openroadm node available for node {}", node);
381             return "";
382         }
383         switch (this.nodeType) {
384             case SRG :
385                 if (node1.getSrgAttributes().getSupportedOperationalModes() == null
386                         || node1.getSrgAttributes().getSupportedOperationalModes().stream().findFirst().isEmpty()) {
387                     LOG.debug("getOperationalMode: SRG has no operational mode declared");
388                     return StringConstants.UNKNOWN_MODE;
389                 } else {
390                     LOG.debug("getOperationalMode: SRG has operational mode declared {}",
391                         node1.getSrgAttributes().getSupportedOperationalModes().stream().findFirst().toString());
392                     return node1.getSrgAttributes().getSupportedOperationalModes().stream().findFirst().toString();
393                 }
394             case DEGREE :
395                 if (node1.getDegreeAttributes().getSupportedOperationalModes() == null
396                         || node1.getDegreeAttributes().getSupportedOperationalModes().stream().findFirst().isEmpty()) {
397                     LOG.debug("getOperationalMode: DEGREE has no operational mode declared");
398                     return StringConstants.UNKNOWN_MODE;
399                 } else {
400                     LOG.debug("getOperationalMode: DEGREE has operational mode declared {}",
401                         node1.getDegreeAttributes().getSupportedOperationalModes().stream().findFirst().toString());
402                     return node1.getDegreeAttributes().getSupportedOperationalModes().stream().findFirst().toString();
403                 }
404             default:
405                 LOG.debug("getOperationalMode: Did not succeed retrieving Operational Mode for the node");
406                 return "";
407         }
408     }
409
410     @Override
411     public String getXponderOperationalMode(XpdrNetworkAttributes tp) {
412         if (tp.getSupportedOperationalModes() == null) {
413             LOG.warn("getOperationalMode: NetworkPort {} has no operational mode declared compatible with service type",
414                 tp);
415             return StringConstants.UNKNOWN_MODE;
416         }
417         for (Map.Entry<OperationalModeKey, OperationalMode> mode : tp.getSupportedOperationalModes()
418                 .getOperationalMode().entrySet()) {
419             if (mode.getKey().toString().contains(StringConstants.SERVICE_TYPE_RATE
420                     .get(this.serviceType).toCanonicalString())) {
421                 LOG.info("getOperationalMode: NetworkPort {}  has {} operational mode declared", tp,
422                     mode.getKey().toString());
423                 return mode.getKey().toString();
424             }
425         }
426         LOG.warn("getOperationalMode: NetworkPort {}  has no operational mode declared compatible with service type",
427             tp);
428         return StringConstants.UNKNOWN_MODE;
429     }
430
431     public void validateAZxponder(String anodeId, String znodeId, ServiceFormat serviceFormat) {
432         if (!isValid() || this.nodeType != OpenroadmNodeType.XPONDER) {
433             return;
434         }
435         // Detect A and Z
436         if (anodeId.contains(this.getSupNetworkNodeId()) || (znodeId.contains(this.getSupNetworkNodeId()))) {
437             LOG.info("validateAZxponder: A or Z node detected == {}", nodeId.getValue());
438             initXndrTps(serviceFormat);
439             return;
440         }
441         LOG.debug("validateAZxponder: XPONDER == {} is ignored, supported by {} for aNodeId {} ", nodeId.getValue(),
442             this.getSupNetworkNodeId(), anodeId);
443         valid = false;
444     }
445
446     @Override
447     public boolean checkTP(String tp) {
448         return !this.usedXpndrNWTps.contains(tp);
449     }
450
451     public boolean isValid() {
452         if (node == null || nodeId == null || nodeType == null || this.getSupNetworkNodeId() == null
453                 || this.getSupClliNodeId() == null || adminStates == null || state == null) {
454             LOG.error("PceNode {},   nodeId {}  NodeType {} : one of parameters is not populated : nodeId, node type,"
455                 + " supporting nodeId, admin state, operational state", deviceNodeId, nodeId, nodeType);
456             valid = false;
457         }
458         return valid;
459     }
460
461     @Override
462     public List<PceLink> getOutgoingLinks() {
463         return outgoingLinks;
464     }
465
466     @Override
467     public AdminStates getAdminStates() {
468         return adminStates;
469     }
470
471     @Override
472     public State getState() {
473         return state;
474     }
475
476     @Override
477     public NodeId getNodeId() {
478         return nodeId;
479     }
480
481     @Override
482     public String toString() {
483         return "PceNode type=" + nodeType + " ID=" + nodeId.getValue() + " CLLI=" + this.getSupClliNodeId();
484     }
485
486     @Override
487     public String getPceNodeType() {
488         return "optical";
489     }
490
491     @Override
492     public String getSupNetworkNodeId() {
493         return MapUtils.getSupNetworkNode(this.node);
494     }
495
496     @Override
497     public String getSupClliNodeId() {
498         return MapUtils.getSupClliNode(this.node);
499     }
500
501     @Override
502     public void addOutgoingLink(PceLink outLink) {
503         this.outgoingLinks.add(outLink);
504     }
505
506     @Override
507     public String getXpdrClient(String tp) {
508         return this.clientPerNwTp.get(tp);
509     }
510
511     @Override
512     public Map<String, List<Uint16>> getAvailableTribPorts() {
513         return null;
514     }
515
516     @Override
517     public OpenroadmNodeType getORNodeType() {
518         return this.nodeType;
519     }
520
521     @Override
522     public Map<String, List<Uint16>> getAvailableTribSlots() {
523         return null;
524     }
525
526     /*
527     * (non-Javadoc)
528     *
529     * @see org.opendaylight.transportpce.pce.networkanalyzer.PceNode#getBitSetData()
530     */
531     @Override
532     public BitSet getBitSetData() {
533         return this.frequenciesBitSet;
534     }
535
536     /*
537     * (non-Javadoc)
538     *
539     * @see org.opendaylight.transportpce.pce.networkanalyzer.PceNode#getVersion()
540     */
541     @Override
542     public String getVersion() {
543         return this.version;
544     }
545
546     /*
547     * (non-Javadoc)
548     *
549     * @see org.opendaylight.transportpce.pce.networkanalyzer.PceNode#getSlotWidthGranularity()
550     */
551     @Override
552     public BigDecimal getSlotWidthGranularity() {
553         return slotWidthGranularity;
554     }
555
556     /*
557      * (non-Javadoc)
558      *
559      * @see org.opendaylight.transportpce.pce.networkanalyzer.PceNode#getCentralFreqGranularity()
560      */
561     @Override
562     public BigDecimal getCentralFreqGranularity() {
563         return centralFreqGranularity;
564     }
565
566     public void setEndpoints(Endpoints endpoints) {
567         this.endpoints = endpoints;
568     }
569
570 }