Fix tapi get-topology-details functional test
[transportpce.git] / tapi / src / main / java / org / opendaylight / transportpce / tapi / topology / TapiNetworkModelServiceImpl.java
1 /*
2  * Copyright © 2021 Nokia, 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 package org.opendaylight.transportpce.tapi.topology;
9
10 import java.nio.charset.Charset;
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.Collection;
14 import java.util.Comparator;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Optional;
19 import java.util.UUID;
20 import java.util.concurrent.ExecutionException;
21 import java.util.stream.Collectors;
22 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
23 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
24 import org.opendaylight.transportpce.tapi.R2RTapiLinkDiscovery;
25 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.mapping.Mapping;
26 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.network.Nodes;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev181019.NodeTypes;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.types.rev191129.XpdrNodeTypes;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev200327.xpdr.odu.switching.pools.OduSwitchingPools;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev200327.xpdr.odu.switching.pools.OduSwitchingPoolsBuilder;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev200327.xpdr.odu.switching.pools.odu.switching.pools.NonBlockingList;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev200327.xpdr.odu.switching.pools.odu.switching.pools.NonBlockingListBuilder;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.types.rev200327.xpdr.odu.switching.pools.odu.switching.pools.NonBlockingListKey;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.OpenroadmNodeType;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.xpdr.tp.supported.interfaces.SupportedInterfaceCapability;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.xpdr.tp.supported.interfaces.SupportedInterfaceCapabilityBuilder;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.xpdr.tp.supported.interfaces.SupportedInterfaceCapabilityKey;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev200327.If100GE;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev200327.If100GEODU4;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev200327.If10GE;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev200327.If10GEODU2;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev200327.If10GEODU2e;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev200327.If1GE;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev200327.If1GEODU0;
47 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev200327.IfOCH;
48 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev200327.IfOCHOTU4ODU4;
49 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev200327.SupportedIfCapability;
50 import org.opendaylight.yang.gen.v1.http.org.openroadm.switching.pool.types.rev191129.SwitchingPoolTypes;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.TpId;
53 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.AdministrativeState;
54 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.CapacityUnit;
55 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.Context;
56 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.ContextBuilder;
57 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.ForwardingDirection;
58 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.LAYERPROTOCOLQUALIFIER;
59 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.LayerProtocolName;
60 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.LifecycleState;
61 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.OperationalState;
62 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.PortDirection;
63 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.PortRole;
64 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.TerminationDirection;
65 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.TerminationState;
66 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.Uuid;
67 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.capacity.TotalSizeBuilder;
68 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.capacity.pac.AvailableCapacityBuilder;
69 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.capacity.pac.TotalPotentialCapacityBuilder;
70 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.Name;
71 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.NameBuilder;
72 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.NameKey;
73 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.tapi.context.ServiceInterfacePoint;
74 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.tapi.context.ServiceInterfacePointBuilder;
75 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.tapi.context.ServiceInterfacePointKey;
76 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection;
77 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionBuilder;
78 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey;
79 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityService;
80 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityServiceBuilder;
81 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityServiceKey;
82 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.EndPoint;
83 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.EndPointKey;
84 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext;
85 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.dsr.rev181210.DIGITALSIGNALTYPE100GigE;
86 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.dsr.rev181210.DIGITALSIGNALTYPE10GigELAN;
87 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.dsr.rev181210.DIGITALSIGNALTYPEGigE;
88 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.odu.rev181210.ODUTYPEODU0;
89 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.odu.rev181210.ODUTYPEODU2;
90 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.odu.rev181210.ODUTYPEODU2E;
91 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.odu.rev181210.ODUTYPEODU4;
92 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.photonic.media.rev181210.PHOTONICLAYERQUALIFIEROMS;
93 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.photonic.media.rev181210.PHOTONICLAYERQUALIFIEROTSi;
94 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.Context1;
95 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.ForwardingRule;
96 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.ProtectionType;
97 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.RestorationPolicy;
98 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.RuleType;
99 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.context.TopologyContext;
100 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.link.NodeEdgePoint;
101 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.link.NodeEdgePointBuilder;
102 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.link.NodeEdgePointKey;
103 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.link.ResilienceTypeBuilder;
104 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.NodeRuleGroup;
105 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.NodeRuleGroupBuilder;
106 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.NodeRuleGroupKey;
107 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePoint;
108 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePointBuilder;
109 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePointKey;
110 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.edge.point.MappedServiceInterfacePoint;
111 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.edge.point.MappedServiceInterfacePointBuilder;
112 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.edge.point.MappedServiceInterfacePointKey;
113 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.Rule;
114 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.RuleBuilder;
115 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.RuleKey;
116 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.risk.parameter.pac.RiskCharacteristic;
117 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.risk.parameter.pac.RiskCharacteristicBuilder;
118 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link;
119 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.LinkBuilder;
120 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.LinkKey;
121 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node;
122 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.NodeBuilder;
123 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.NodeKey;
124 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.Topology;
125 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.TopologyBuilder;
126 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.TopologyKey;
127 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.transfer.cost.pac.CostCharacteristic;
128 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.transfer.cost.pac.CostCharacteristicBuilder;
129 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.transfer.timing.pac.LatencyCharacteristic;
130 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.transfer.timing.pac.LatencyCharacteristicBuilder;
131 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.validation.pac.ValidationMechanism;
132 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.validation.pac.ValidationMechanismBuilder;
133 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
134 import org.opendaylight.yangtools.yang.common.Uint16;
135 import org.opendaylight.yangtools.yang.common.Uint32;
136 import org.opendaylight.yangtools.yang.common.Uint64;
137 import org.slf4j.Logger;
138 import org.slf4j.LoggerFactory;
139
140 public class TapiNetworkModelServiceImpl implements TapiNetworkModelService {
141
142     private static final Logger LOG = LoggerFactory.getLogger(TapiNetworkModelServiceImpl.class);
143     private static final String DSR = "DSR";
144     private static final String I_ODU = "iODU";
145     private static final String E_ODU = "eODU";
146     private static final String OTSI = "OTSi";
147     private static final String E_OTSI = "eOTSi";
148     private static final String I_OTSI = "iOTSi";
149     private static final String PHTNC_MEDIA = "PHOTONIC_MEDIA";
150     private static final String MC = "MEDIA_CHANNEL";
151     private static final String OTSI_MC = "OTSi_MEDIA_CHANNEL";
152     private static final String CLIENT = "-CLIENT";
153     private static final String NETWORK = "-NETWORK";
154     private static final String XPDR = "-XPDR";
155     private final Uuid tapiTopoUuid = new Uuid(UUID.nameUUIDFromBytes(TopologyUtils.T0_FULL_MULTILAYER
156             .getBytes(Charset.forName("UTF-8"))).toString());
157     private final NetworkTransactionService networkTransactionService;
158     private Map<ServiceInterfacePointKey, ServiceInterfacePoint> sipMap;
159     private final R2RTapiLinkDiscovery linkDiscovery;
160
161     public TapiNetworkModelServiceImpl(final R2RTapiLinkDiscovery linkDiscovery,
162                                        NetworkTransactionService networkTransactionService) {
163         this.networkTransactionService = networkTransactionService;
164         this.sipMap = new HashMap<>();
165         this.linkDiscovery = linkDiscovery;
166     }
167
168     @Override
169     public void createTapiNode(String orNodeId, int orNodeVersion, Nodes node) {
170         // TODO -> Implementation with PortMappingListener
171         // check if port mapping exists or not...
172         if (node.getMapping() == null) {
173             LOG.warn("Could not generate port mapping for {} skipping network model creation", orNodeId);
174             return;
175         }
176         this.sipMap.clear();
177         LOG.info("Mapping of node {}: {}", orNodeId, node.getMapping().values());
178
179         // check type of device, check version and create node mapping
180         if (NodeTypes.Rdm.getIntValue() == node.getNodeInfo().getNodeType().getIntValue()) {
181             // ROADM device
182             // transform flat mapping list to per degree and per srg mapping lists
183             Map<String, List<Mapping>> mapDeg = new HashMap<>();
184             Map<String, List<Mapping>> mapSrg = new HashMap<>();
185             List<Mapping> mappingList = new ArrayList<>(node.nonnullMapping().values());
186             mappingList.sort(Comparator.comparing(Mapping::getLogicalConnectionPoint));
187
188             List<String> nodeShardList = getRoadmNodelist(mappingList);
189
190             // populate degree and srg LCP map
191             for (String str : nodeShardList) {
192                 List<Mapping> interList = mappingList.stream().filter(x -> x.getLogicalConnectionPoint().contains(str))
193                         .collect(Collectors.toList());
194                 if (str.contains("DEG")) {
195                     mapDeg.put(str, interList);
196                 } else if (str.contains("SRG")) {
197                     mapSrg.put(str, interList);
198                 } else {
199                     LOG.error("unknown element");
200                 }
201             }
202             // Transform LCPs into ONEP
203             Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> onepMap =
204                 new HashMap<>(transformDegToOnep(orNodeId, mapDeg));
205             onepMap.putAll(transformSrgToOnep(orNodeId, mapSrg));
206
207             // create tapi Node
208             org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node roadmNode =
209                     createRoadmTapiNode(orNodeId, onepMap);
210             mergeNodeinTopology(Map.of(roadmNode.key(), roadmNode));
211             mergeSipsinContext(this.sipMap);
212             // TODO add states corresponding to device config -> based on mapping.
213             //  This should be possible after Gilles work is merged
214
215             // rdm to rdm link creation if neighbour roadm is mounted
216             LOG.info("checking if neighbor roadm exists");
217             Map<LinkKey, Link> rdm2rdmLinks = this.linkDiscovery.readLLDP(new NodeId(orNodeId), orNodeVersion,
218                 this.tapiTopoUuid);
219             if (!rdm2rdmLinks.isEmpty()) {
220                 mergeLinkinTopology(rdm2rdmLinks);
221             }
222             LOG.info("TAPI node for or node {} successfully merged", orNodeId);
223         } else if (NodeTypes.Xpdr.getIntValue() ==  node.getNodeInfo().getNodeType().getIntValue()) {
224             List<Mapping> networkMappings = node.nonnullMapping().values()
225                     .stream().filter(k -> k.getLogicalConnectionPoint()
226                             .contains("NETWORK")).collect(Collectors.toList());
227             Map<Integer, String> xpdrMap = new HashMap<>();
228             for (Mapping mapping : networkMappings) {
229                 Integer xpdrNb = Integer.parseInt(mapping.getLogicalConnectionPoint().split("XPDR")[1].split("-")[0]);
230                 String nodeId = node.getNodeId() + XPDR + xpdrNb;
231                 if (!xpdrMap.containsKey(xpdrNb)) {
232                     List<Mapping> xpdrNetMaps = node.nonnullMapping().values()
233                             .stream().filter(k -> k.getLogicalConnectionPoint()
234                                     .contains("XPDR" + xpdrNb + NETWORK)).collect(Collectors.toList());
235                     List<Mapping> xpdrClMaps = node.nonnullMapping().values()
236                             .stream().filter(k -> k.getLogicalConnectionPoint()
237                                     .contains("XPDR" + xpdrNb + CLIENT)).collect(Collectors.toList());
238                     xpdrMap.put(xpdrNb, node.getNodeId());
239
240                     // create switching pool
241                     OduSwitchingPools oorOduSwitchingPool = createSwitchPoolForXpdr(
242                         mapping.getXponderType().getIntValue(), xpdrClMaps, xpdrNetMaps, xpdrNb);
243
244                     // node transformation
245                     Map<NodeKey, Node> nodeMap = new HashMap<>(transformXpdrToTapiNode(
246                         nodeId, xpdrClMaps, xpdrNetMaps, mapping.getXponderType(), oorOduSwitchingPool));
247                     // add nodes and sips to tapi context
248                     mergeNodeinTopology(nodeMap);
249                     mergeSipsinContext(this.sipMap);
250                 }
251             }
252             LOG.info("TAPI node for or node {} successfully merged", orNodeId);
253         }
254         // Device not managed yet
255     }
256
257     private Map<NodeKey, Node> transformXpdrToTapiNode(String nodeId, List<Mapping> xpdrClMaps,
258                                                        List<Mapping> xpdrNetMaps, XpdrNodeTypes xponderType,
259                                                        OduSwitchingPools oorOduSwitchingPool) {
260         Map<NodeKey, Node> nodeMap = new HashMap<>();
261         LOG.info("creation of a DSR/ODU node for {}", nodeId);
262         Uuid nodeUuidDsr = new Uuid(UUID.nameUUIDFromBytes((String.join("+", nodeId, DSR))
263             .getBytes(Charset.forName("UTF-8"))).toString());
264         Name nameDsr = new NameBuilder().setValueName("dsr/odu node name").setValue(
265             String.join("+", nodeId, DSR)).build();
266         List<LayerProtocolName> dsrLayerProtocols = Arrays.asList(LayerProtocolName.DSR,
267             LayerProtocolName.ODU);
268         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology
269             .Node dsrNode = createTapiXpdrNode(Map.of(nameDsr.key(), nameDsr), dsrLayerProtocols,
270             nodeId, nodeUuidDsr, xpdrClMaps, xpdrNetMaps, xponderType, oorOduSwitchingPool);
271
272         nodeMap.put(dsrNode.key(), dsrNode);
273
274         // node creation [otsi]
275         LOG.info("creation of an OTSi node for {}", nodeId);
276         Uuid nodeUuidOtsi = new Uuid(UUID.nameUUIDFromBytes((String.join("+", nodeId, OTSI))
277             .getBytes(Charset.forName("UTF-8"))).toString());
278         Name nameOtsi =  new NameBuilder().setValueName("otsi node name").setValue(
279             String.join("+", nodeId, OTSI)).build();
280         List<LayerProtocolName> otsiLayerProtocols = Arrays.asList(LayerProtocolName.PHOTONICMEDIA);
281         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology
282             .Node otsiNode = createTapiXpdrNode(Map.of(nameOtsi.key(), nameOtsi), otsiLayerProtocols,
283             nodeId, nodeUuidOtsi, xpdrClMaps, xpdrNetMaps, xponderType, null);
284
285         nodeMap.put(otsiNode.key(), otsiNode);
286
287         // transitional link cration between network nep of DSR/ODU node and iNep of otsi node
288         LOG.info("creation of transitional links between DSR/ODU and OTSi nodes");
289         Map<LinkKey, Link> linkMap = createTapiTransitionalLinks(nodeId, xpdrNetMaps, nodeUuidDsr,
290             nodeUuidOtsi);
291         mergeLinkinTopology(linkMap);
292
293         return nodeMap;
294     }
295
296     private OduSwitchingPools createSwitchPoolForXpdr(int xpdrType, List<Mapping> xpdrClMaps, List<Mapping> xpdrNetMaps,
297                                                       Integer xpdrNb) {
298         // todo: are switching pool correct here??
299         switch (xpdrType) {
300             case 1:
301                 // Tpdr
302                 return createTpdrSwitchPool();
303             case 2:
304                 // Mux
305                 return createMuxSwitchPool(xpdrClMaps, xpdrNetMaps, xpdrNb);
306             case 3:
307                 // Switch
308                 return createSwtchSwitchPool(xpdrClMaps, xpdrNetMaps, xpdrNb);
309             default:
310                 LOG.warn("Xpdr type {} not supported", xpdrType);
311         }
312         return null;
313     }
314
315     private Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> transformSrgToOnep(String orNodeId,
316                                                                               Map<String, List<Mapping>> mapSrg) {
317         Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> onepMap = new HashMap<>();
318         for (Map.Entry<String, List<Mapping>> entry : mapSrg.entrySet()) {
319             // For each srg node. Loop through the LCPs and create neps and sips for PP
320             for (Mapping m:entry.getValue()) {
321                 if (!m.getLogicalConnectionPoint().contains("PP")) {
322                     LOG.info("LCP {} is not an external TP of SRG node", m.getLogicalConnectionPoint());
323                     continue;
324                 }
325                 Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> srgNeps =
326                     createRoadmNeps(orNodeId, m.getLogicalConnectionPoint(), true,
327                             transformOperState(m.getPortOperState()), transformAdminState(m.getPortAdminState()));
328                 onepMap.putAll(srgNeps);
329             }
330         }
331         return onepMap;
332     }
333
334     private Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> transformDegToOnep(String orNodeId,
335                                                                               Map<String, List<Mapping>> mapDeg) {
336         Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> onepMap = new HashMap<>();
337         for (Map.Entry<String, List<Mapping>> entry : mapDeg.entrySet()) {
338             // For each degree node. Loop through the LCPs and create neps and sips for TTP
339             for (Mapping m:entry.getValue()) {
340                 if (!m.getLogicalConnectionPoint().contains("TTP")) {
341                     LOG.info("LCP {} is not an external TP of DEGREE node", m.getLogicalConnectionPoint());
342                     continue;
343                 }
344                 Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> degNeps =
345                     createRoadmNeps(orNodeId, m.getLogicalConnectionPoint(), false,
346                             transformOperState(m.getPortOperState()), transformAdminState(m.getPortAdminState()));
347                 onepMap.putAll(degNeps);
348             }
349         }
350         return onepMap;
351     }
352
353     private List<String> getRoadmNodelist(List<Mapping> mappingList) {
354         List<String> nodeShardList = new ArrayList<>();
355         for (Mapping mapping : mappingList) {
356             // TODO -> maybe we need to check the id based on the version
357             String str = mapping.getLogicalConnectionPoint().split("-")[0];
358             LOG.info("LCP = {}", str);
359             if (!nodeShardList.contains(str)) {
360                 nodeShardList.add(str);
361             }
362         }
363         return nodeShardList;
364     }
365
366     @Override
367     public void deleteTapinode(String nodeId) {
368         // TODO: check for null objects
369         // Check if it is ROADM or XPDR --> create the uuids of the node and delete from topology the node.
370         // This will delete NEPs. Then check for links that have this node and delete them.
371         // Then check SIPs and delete them. Then services and connections with SIPs and put them to another state.
372         LOG.info("Deleting node {} from TAPI topology", nodeId);
373         InstanceIdentifier<Topology> topologyIID = InstanceIdentifier.builder(Context.class)
374                 .augmentation(Context1.class).child(TopologyContext.class).child(Topology.class,
375                         new TopologyKey(tapiTopoUuid)).build();
376         Topology topology = null;
377         try {
378             Optional<Topology> optTopology =
379                     this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, topologyIID).get();
380             if (!optTopology.isPresent()) {
381                 LOG.error("No topology object present. Error deleting node {}", nodeId);
382                 return;
383             }
384             topology = optTopology.get();
385         } catch (InterruptedException | ExecutionException e) {
386             LOG.error("Couldnt read tapi topology from datastore", e);
387         }
388         if (topology == null) {
389             LOG.error("Topology is null, nothing to delete");
390             return;
391         }
392         if (topology.getNode() == null) {
393             LOG.error("No nodes in topology");
394             return;
395         }
396         if (nodeId.contains("ROADM")) {
397             // Node is in photonic media layer and UUID can be built from nodeId + PHTN_MEDIA
398             Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", nodeId, PHTNC_MEDIA))
399                     .getBytes(Charset.forName("UTF-8"))).toString());
400             deleteNodeFromTopo(nodeUuid);
401         }
402         if (nodeId.contains("XPDR") || nodeId.contains("SPDR") || nodeId.contains("MXPDR")) {
403             // Node is either XPDR, MXPDR or SPDR. Retrieve nodes from topology and check names
404             for (Node tapiNode:topology.getNode().values()) {
405                 if (tapiNode.getName().values().stream().anyMatch(name -> name.getValue().contains(nodeId))) {
406                     // Found node we need to delete
407                     deleteNodeFromTopo(tapiNode.getUuid());
408                 }
409             }
410         }
411         // Delete links of topology
412         Map<LinkKey, Link> linkMap = topology.getLink();
413         if (linkMap != null) {
414             for (Link link:linkMap.values()) {
415                 if (link.getName().values().stream().anyMatch(name -> name.getValue().contains(nodeId))) {
416                     deleteLinkFromTopo(link.getUuid());
417                 }
418             }
419         }
420         // Delete sips of sip map
421         InstanceIdentifier<Context> contextIID = InstanceIdentifier.builder(Context.class).build();
422         Context context = null;
423         try {
424             Optional<Context> optContext = this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL,
425                     contextIID).get();
426             if (!optContext.isPresent()) {
427                 LOG.error("No context object present in datastore.");
428                 return;
429             }
430             context = optContext.get();
431         } catch (InterruptedException | ExecutionException e) {
432             LOG.error("Couldnt read tapi context from datastore", e);
433         }
434         if (context == null) {
435             LOG.error("Context is null, nothing to delete");
436             return;
437         }
438         Map<ServiceInterfacePointKey, ServiceInterfacePoint> sips = context.getServiceInterfacePoint();
439         if (sips != null) {
440             for (ServiceInterfacePoint sip:sips.values()) {
441                 if (sip.getName().values().stream().anyMatch(name -> name.getValue().contains(nodeId))) {
442                     // Update state of services that have this sip as an endpoint and also connections
443                     updateConnectivityServicesState(sip.getUuid(), nodeId);
444                     deleteSipFromTopo(sip.getUuid());
445                 }
446             }
447         }
448     }
449
450     private Node createTapiXpdrNode(Map<NameKey, Name> nameMap, List<LayerProtocolName> layerProtocols,
451                                     String nodeId, Uuid nodeUuid, List<Mapping> xpdrClMaps, List<Mapping> xpdrNetMaps,
452                                     XpdrNodeTypes xponderType, OduSwitchingPools oorOduSwitchingPool) {
453         Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> onepl = new HashMap<>();
454         Map<NodeRuleGroupKey, NodeRuleGroup> nodeRuleGroupList = new HashMap<>();
455         Map<RuleKey, Rule> ruleList = new HashMap<>();
456         Rule rule = new RuleBuilder()
457                 .setLocalId("forward")
458                 .setForwardingRule(ForwardingRule.MAYFORWARDACROSSGROUP)
459                 .setRuleType(RuleType.FORWARDING)
460                 .build();
461         ruleList.put(rule.key(), rule);
462         if (layerProtocols.contains(LayerProtocolName.DSR)) {
463             // neps for dsr/odu layer
464             Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> dsroduNeps =
465                     createXpdrDsrOduNeps(nodeId, xpdrClMaps, xpdrNetMaps, xponderType);
466             onepl.putAll(dsroduNeps);
467             nodeRuleGroupList = createNodeRuleGroupForDsrNode(nodeId, oorOduSwitchingPool, ruleList, onepl);
468         } else if (layerProtocols.contains(LayerProtocolName.PHOTONICMEDIA)) {
469             // neps for photonic layer
470             Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> phtmdNeps =
471                     createXpdrPhtnMdNeps(nodeId, xpdrNetMaps);
472             onepl.putAll(phtmdNeps);
473             nodeRuleGroupList = createNodeRuleGroupForOtsiNode(nodeId, xpdrNetMaps, ruleList);
474         } else {
475             LOG.error("Undefined LayerProtocolName for {} node {}", nameMap.get(nameMap.keySet().iterator().next())
476                     .getValueName(), nameMap.get(nameMap.keySet().iterator().next()).getValue());
477         }
478         // Empty random creation of mandatory fields for avoiding errors....
479         CostCharacteristic costCharacteristic = new CostCharacteristicBuilder()
480             .setCostAlgorithm("Restricted Shortest Path - RSP")
481             .setCostName("HOP_COUNT")
482             .setCostValue("12345678")
483             .build();
484         LatencyCharacteristic latencyCharacteristic = new LatencyCharacteristicBuilder()
485             .setFixedLatencyCharacteristic("12345678")
486             .setQueingLatencyCharacteristic("12345678")
487             .setJitterCharacteristic("12345678")
488             .setWanderCharacteristic("12345678")
489             .setTrafficPropertyName("FIXED_LATENCY")
490             .build();
491         return new NodeBuilder()
492             .setUuid(nodeUuid)
493             .setName(nameMap)
494             .setLayerProtocolName(layerProtocols)
495             .setAdministrativeState(AdministrativeState.UNLOCKED)
496             .setOperationalState(OperationalState.ENABLED)
497             .setLifecycleState(LifecycleState.INSTALLED)
498             .setOwnedNodeEdgePoint(onepl)
499             .setNodeRuleGroup(nodeRuleGroupList)
500             .setCostCharacteristic(Map.of(costCharacteristic.key(), costCharacteristic))
501             .setLatencyCharacteristic(Map.of(latencyCharacteristic.key(), latencyCharacteristic))
502             .setErrorCharacteristic("error")
503             .setLossCharacteristic("loss")
504             .setRepeatDeliveryCharacteristic("repeat delivery")
505             .setDeliveryOrderCharacteristic("delivery order")
506             .setUnavailableTimeCharacteristic("unavailable time")
507             .setServerIntegrityProcessCharacteristic("server integrity process")
508             .build();
509     }
510
511     private Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> createXpdrPhtnMdNeps(String nodeId,
512                                                                                 List<Mapping> xpdrNetMaps) {
513         Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> onepl = new HashMap<>();
514
515         // iNep creation on otsi node
516         for (int i = 0; i < xpdrNetMaps.size(); i++) {
517             Uuid nepUuid1 = new Uuid(UUID.nameUUIDFromBytes(
518                     (String.join("+", nodeId, I_OTSI, xpdrNetMaps.get(i).getLogicalConnectionPoint()))
519                             .getBytes(Charset.forName("UTF-8")))
520                     .toString());
521             Name onedName = new NameBuilder()
522                     .setValueName("iNodeEdgePoint")
523                     .setValue(String.join("+", nodeId, I_OTSI, xpdrNetMaps.get(i).getLogicalConnectionPoint()))
524                     .build();
525
526             OwnedNodeEdgePoint onep = createNep(nepUuid1, xpdrNetMaps.get(i).getLogicalConnectionPoint(),
527                 Map.of(onedName.key(), onedName), LayerProtocolName.PHOTONICMEDIA, LayerProtocolName.PHOTONICMEDIA,
528                 true, String.join("+", nodeId, I_OTSI),
529                 xpdrNetMaps.get(i).getSupportedInterfaceCapability(),
530                 transformOperState(xpdrNetMaps.get(i).getPortOperState()),
531                 transformAdminState(xpdrNetMaps.get(i).getPortAdminState()));
532             onepl.put(onep.key(), onep);
533         }
534         // eNep creation on otsi node
535         for (int i = 0; i < xpdrNetMaps.size(); i++) {
536             Uuid nepUuid2 = new Uuid(UUID.nameUUIDFromBytes(
537                     (String.join("+", nodeId, E_OTSI, xpdrNetMaps.get(i).getLogicalConnectionPoint()))
538                             .getBytes(Charset.forName("UTF-8"))).toString());
539             Name onedName = new NameBuilder()
540                     .setValueName("eNodeEdgePoint")
541                     .setValue(String.join("+", nodeId, E_OTSI, xpdrNetMaps.get(i).getLogicalConnectionPoint()))
542                     .build();
543
544             OwnedNodeEdgePoint onep = createNep(nepUuid2, xpdrNetMaps.get(i).getLogicalConnectionPoint(),
545                 Map.of(onedName.key(), onedName), LayerProtocolName.PHOTONICMEDIA, LayerProtocolName.PHOTONICMEDIA,
546                 false, String.join("+", nodeId, E_OTSI),
547                 xpdrNetMaps.get(i).getSupportedInterfaceCapability(),
548                 transformOperState(xpdrNetMaps.get(i).getPortOperState()),
549                 transformAdminState(xpdrNetMaps.get(i).getPortAdminState()));
550             onepl.put(onep.key(), onep);
551         }
552         // Photonic Media Nep creation on otsi node
553         for (int i = 0; i < xpdrNetMaps.size(); i++) {
554             Uuid nepUuid3 = new Uuid(UUID.nameUUIDFromBytes(
555                     (String.join("+", nodeId, PHTNC_MEDIA, xpdrNetMaps.get(i).getLogicalConnectionPoint()))
556                             .getBytes(Charset.forName("UTF-8"))).toString());
557             Name onedName = new NameBuilder()
558                     .setValueName("PhotMedNodeEdgePoint")
559                     .setValue(String.join("+", nodeId, PHTNC_MEDIA, xpdrNetMaps.get(i).getLogicalConnectionPoint()))
560                     .build();
561
562             OwnedNodeEdgePoint onep = createNep(nepUuid3, xpdrNetMaps.get(i).getLogicalConnectionPoint(),
563                 Map.of(onedName.key(), onedName), LayerProtocolName.PHOTONICMEDIA, LayerProtocolName.PHOTONICMEDIA,
564                 false, String.join("+", nodeId, PHTNC_MEDIA),
565                 xpdrNetMaps.get(i).getSupportedInterfaceCapability(),
566                 transformOperState(xpdrNetMaps.get(i).getPortOperState()),
567                 transformAdminState(xpdrNetMaps.get(i).getPortAdminState()));
568             onepl.put(onep.key(), onep);
569         }
570         return onepl;
571     }
572
573     private Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> createXpdrDsrOduNeps(String nodeId, List<Mapping> xpdrClMaps,
574                                                                                 List<Mapping> xpdrNetMaps,
575                                                                                 XpdrNodeTypes xponderType) {
576         Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> onepl = new HashMap<>();
577         // client nep creation on DSR node
578         for (int i = 0; i < xpdrClMaps.size(); i++) {
579             LOG.info("Client NEP = {}", String.join("+", nodeId, DSR, xpdrClMaps.get(i).getLogicalConnectionPoint()));
580             Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(
581                     (String.join("+", nodeId, DSR, xpdrClMaps.get(i).getLogicalConnectionPoint()))
582                             .getBytes(Charset.forName("UTF-8"))).toString());
583             NameBuilder nameBldr = new NameBuilder().setValue(
584                 String.join("+", nodeId, DSR, xpdrClMaps.get(i).getLogicalConnectionPoint()));
585             Name name;
586             if (OpenroadmNodeType.TPDR.getName().equalsIgnoreCase(xponderType.getName())) {
587                 name = nameBldr.setValueName("100G-tpdr").build();
588             } else {
589                 name = nameBldr.setValueName("NodeEdgePoint_C").build();
590             }
591
592             OwnedNodeEdgePoint onep = createNep(nepUuid, xpdrClMaps.get(i).getLogicalConnectionPoint(),
593                 Map.of(name.key(), name), LayerProtocolName.DSR, LayerProtocolName.DSR, true,
594                 String.join("+", nodeId, DSR), xpdrClMaps.get(i).getSupportedInterfaceCapability(),
595                 transformOperState(xpdrClMaps.get(i).getPortOperState()),
596                 transformAdminState(xpdrClMaps.get(i).getPortAdminState()));
597             onepl.put(onep.key(), onep);
598         }
599         // network nep creation on I_ODU node
600         for (int i = 0; i < xpdrNetMaps.size(); i++) {
601             LOG.info("iODU NEP = {}", String.join("+", nodeId, I_ODU, xpdrNetMaps.get(i).getLogicalConnectionPoint()));
602             Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(
603                     (String.join("+", nodeId, I_ODU, xpdrNetMaps.get(i).getLogicalConnectionPoint()))
604                             .getBytes(Charset.forName("UTF-8"))).toString());
605             Name onedName = new NameBuilder()
606                     .setValueName("iNodeEdgePoint_N")
607                     .setValue(String.join("+", nodeId, I_ODU, xpdrNetMaps.get(i).getLogicalConnectionPoint()))
608                     .build();
609
610             OwnedNodeEdgePoint onep = createNep(nepUuid, xpdrNetMaps.get(i).getLogicalConnectionPoint(),
611                 Map.of(onedName.key(), onedName),
612                 LayerProtocolName.ODU, LayerProtocolName.DSR, false,
613                 String.join("+", nodeId, I_ODU), xpdrNetMaps.get(i).getSupportedInterfaceCapability(),
614                 transformOperState(xpdrNetMaps.get(i).getPortOperState()),
615                 transformAdminState(xpdrNetMaps.get(i).getPortAdminState()));
616             onepl.put(onep.key(), onep);
617         }
618         // network nep creation on E_ODU node
619         for (int i = 0; i < xpdrNetMaps.size(); i++) {
620             LOG.info("eODU NEP = {}", String.join("+", nodeId, E_ODU,
621                 xpdrNetMaps.get(i).getLogicalConnectionPoint()));
622             Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(
623                     (String.join("+", nodeId, E_ODU, xpdrNetMaps.get(i).getLogicalConnectionPoint()))
624                             .getBytes(Charset.forName("UTF-8"))).toString());
625             Name onedName = new NameBuilder()
626                     .setValueName("eNodeEdgePoint_N")
627                     .setValue(String.join("+", nodeId, E_ODU, xpdrNetMaps.get(i).getLogicalConnectionPoint()))
628                     .build();
629
630             OwnedNodeEdgePoint onep = createNep(nepUuid, xpdrNetMaps.get(i).getLogicalConnectionPoint(),
631                 Map.of(onedName.key(), onedName),
632                 LayerProtocolName.ODU, LayerProtocolName.DSR, true,
633                 String.join("+", nodeId, E_ODU), xpdrNetMaps.get(i).getSupportedInterfaceCapability(),
634                 transformOperState(xpdrNetMaps.get(i).getPortOperState()),
635                 transformAdminState(xpdrNetMaps.get(i).getPortAdminState()));
636             onepl.put(onep.key(), onep);
637         }
638         return onepl;
639     }
640
641     private OperationalState transformOperState(String operString) {
642         State operState = org.opendaylight.transportpce.networkmodel.util.TopologyUtils.setNetworkOperState(operString);
643         return operState.equals(State.InService) ? OperationalState.ENABLED : OperationalState.DISABLED;
644     }
645
646     private AdministrativeState transformAdminState(String adminString) {
647         AdminStates adminState = org.opendaylight.transportpce.networkmodel.util.TopologyUtils
648                 .setNetworkAdminState(adminString);
649         return adminState.equals(AdminStates.InService) ? AdministrativeState.UNLOCKED : AdministrativeState.LOCKED;
650     }
651
652     private OwnedNodeEdgePoint createNep(Uuid nepUuid, String tpid, Map<NameKey, Name> nepNames,
653                                          LayerProtocolName nepProtocol, LayerProtocolName nodeProtocol, boolean withSip,
654                                          String keyword,
655                                          List<Class<? extends SupportedIfCapability>> supportedInterfaceCapability,
656                                          OperationalState operState, AdministrativeState adminState) {
657         OwnedNodeEdgePointBuilder onepBldr = new OwnedNodeEdgePointBuilder()
658                 .setUuid(nepUuid)
659                 .setLayerProtocolName(nepProtocol)
660                 .setName(nepNames);
661         if (withSip) {
662             onepBldr.setMappedServiceInterfacePoint(createMSIP(1, nepProtocol, tpid, keyword,
663                     supportedInterfaceCapability, operState, adminState));
664         }
665         LOG.debug("Node layer {}", nodeProtocol.getName());
666         onepBldr.setSupportedCepLayerProtocolQualifier(createSupportedLayerProtocolQualifier(
667                 supportedInterfaceCapability, nodeProtocol));
668         onepBldr.setLinkPortDirection(PortDirection.BIDIRECTIONAL).setLinkPortRole(PortRole.SYMMETRIC)
669                 .setAdministrativeState(adminState).setOperationalState(operState)
670                 .setLifecycleState(LifecycleState.INSTALLED).setTerminationDirection(TerminationDirection.BIDIRECTIONAL)
671                 .setTerminationState(TerminationState.TERMINATEDBIDIRECTIONAL);
672         return onepBldr.build();
673     }
674
675     private Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> createRoadmNeps(String orNodeId, String tpId,
676                                                                            boolean withSip, OperationalState operState,
677                                                                            AdministrativeState adminState) {
678         Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> onepMap = new HashMap<>();
679         // PHOTONIC MEDIA nep
680         Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", orNodeId, PHTNC_MEDIA, tpId))
681                 .getBytes(Charset.forName("UTF-8")))
682                 .toString());
683         Name nepName = new NameBuilder()
684                 .setValueName(PHTNC_MEDIA + "NodeEdgePoint")
685                 .setValue(String.join("+", orNodeId, PHTNC_MEDIA, tpId))
686                 .build();
687         OwnedNodeEdgePoint onep = new OwnedNodeEdgePointBuilder()
688             .setUuid(nepUuid)
689             .setLayerProtocolName(LayerProtocolName.PHOTONICMEDIA)
690             .setName(Map.of(nepName.key(), nepName))
691             .setSupportedCepLayerProtocolQualifier(List.of(PHOTONICLAYERQUALIFIEROMS.class))
692             .setLinkPortDirection(PortDirection.BIDIRECTIONAL).setLinkPortRole(PortRole.SYMMETRIC)
693             .setAdministrativeState(adminState).setOperationalState(operState)
694             .setLifecycleState(LifecycleState.INSTALLED).setTerminationDirection(TerminationDirection.BIDIRECTIONAL)
695             .setTerminationState(TerminationState.TERMINATEDBIDIRECTIONAL)
696             .build();
697         onepMap.put(onep.key(), onep);
698
699         // MC nep
700         Uuid nepUuid1 = new Uuid(UUID.nameUUIDFromBytes((String.join("+", orNodeId, MC, tpId))
701                 .getBytes(Charset.forName("UTF-8")))
702                 .toString());
703         Name nepName1 = new NameBuilder()
704                 .setValueName(MC + "NodeEdgePoint")
705                 .setValue(String.join("+", orNodeId, MC, tpId))
706                 .build();
707         OwnedNodeEdgePointBuilder onepBldr1 = new OwnedNodeEdgePointBuilder()
708                 .setUuid(nepUuid1)
709                 .setLayerProtocolName(LayerProtocolName.PHOTONICMEDIA)
710                 .setName(Map.of(nepName1.key(), nepName1))
711                 .setSupportedCepLayerProtocolQualifier(List.of(PHOTONICLAYERQUALIFIEROMS.class))
712                 .setLinkPortDirection(PortDirection.BIDIRECTIONAL).setLinkPortRole(PortRole.SYMMETRIC)
713                 .setAdministrativeState(adminState).setOperationalState(operState)
714                 .setLifecycleState(LifecycleState.INSTALLED).setTerminationDirection(TerminationDirection.BIDIRECTIONAL)
715                 .setTerminationState(TerminationState.TERMINATEDBIDIRECTIONAL);
716         if (withSip) {
717             onepBldr1.setMappedServiceInterfacePoint(createMSIP(1, LayerProtocolName.PHOTONICMEDIA,
718                     tpId, String.join("+", orNodeId, MC), null, operState, adminState));
719         }
720         OwnedNodeEdgePoint onep1 = onepBldr1.build();
721         onepMap.put(onep1.key(), onep1);
722
723         // OTSiMC nep
724         Uuid nepUuid2 = new Uuid(UUID.nameUUIDFromBytes((String.join("+", orNodeId, OTSI_MC, tpId))
725                 .getBytes(Charset.forName("UTF-8")))
726                 .toString());
727         Name nepName2 = new NameBuilder()
728                 .setValueName(OTSI_MC + "NodeEdgePoint")
729                 .setValue(String.join("+", orNodeId, OTSI_MC, tpId))
730                 .build();
731
732         OwnedNodeEdgePoint onep2 = new OwnedNodeEdgePointBuilder()
733             .setUuid(nepUuid2)
734             .setLayerProtocolName(LayerProtocolName.PHOTONICMEDIA)
735             .setName(Map.of(nepName2.key(), nepName2))
736             .setSupportedCepLayerProtocolQualifier(List.of(PHOTONICLAYERQUALIFIEROMS.class))
737             .setLinkPortDirection(PortDirection.BIDIRECTIONAL).setLinkPortRole(PortRole.SYMMETRIC)
738             .setAdministrativeState(adminState).setOperationalState(operState)
739             .setLifecycleState(LifecycleState.INSTALLED).setTerminationDirection(TerminationDirection.BIDIRECTIONAL)
740             .setTerminationState(TerminationState.TERMINATEDBIDIRECTIONAL)
741             .build();
742         onepMap.put(onep2.key(), onep2);
743         return onepMap;
744     }
745
746     private Map<MappedServiceInterfacePointKey, MappedServiceInterfacePoint>
747             createMSIP(int nb, LayerProtocolName layerProtocol, String tpid, String nodeid,
748                    List<Class<? extends SupportedIfCapability>> supportedInterfaceCapability,
749                    OperationalState operState, AdministrativeState adminState) {
750         Map<MappedServiceInterfacePointKey, MappedServiceInterfacePoint> msipl = new HashMap<>();
751         for (int i = 0; i < nb; i++) {
752             Uuid sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", nodeid,
753                     tpid)).getBytes(Charset.forName("UTF-8"))).toString());
754             MappedServiceInterfacePoint msip = new MappedServiceInterfacePointBuilder()
755                     .setServiceInterfacePointUuid(sipUuid).build();
756             org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.tapi.context.ServiceInterfacePoint sip
757                     = createSIP(sipUuid, layerProtocol, tpid, nodeid, supportedInterfaceCapability,
758                     operState, adminState);
759             this.sipMap.put(sip.key(), sip);
760             LOG.info("SIP created {}", sip.getUuid());
761             // this.tapiSips.put(sip.key(), sip);
762             msipl.put(msip.key(), msip);
763         }
764         return msipl;
765     }
766
767     private ServiceInterfacePoint createSIP(Uuid sipUuid, LayerProtocolName layerProtocol, String tpid, String nodeid,
768                                             List<Class<? extends SupportedIfCapability>> supportedInterfaceCapability,
769                                             OperationalState operState, AdministrativeState adminState) {
770         // TODO: what value should be set in total capacity and available capacity
771         LOG.info("SIP name = {}", String.join("+", nodeid, tpid));
772         Name sipName = new NameBuilder()
773                 .setValueName("SIP name")
774                 .setValue(String.join("+", nodeid, tpid))
775                 .build();
776         return new ServiceInterfacePointBuilder()
777                 .setUuid(sipUuid)
778                 .setName(Map.of(sipName.key(), sipName))
779                 .setLayerProtocolName(layerProtocol)
780                 .setAdministrativeState(adminState)
781                 .setOperationalState(operState)
782                 .setLifecycleState(LifecycleState.INSTALLED)
783                 .setAvailableCapacity(new AvailableCapacityBuilder().build())
784                 .setTotalPotentialCapacity(new TotalPotentialCapacityBuilder().build())
785                 .setSupportedLayerProtocolQualifier(createSupportedLayerProtocolQualifier(supportedInterfaceCapability,
786                         layerProtocol))
787                 .build();
788     }
789
790     private org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node
791             createRoadmTapiNode(String orNodeId, Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> oneplist) {
792         // UUID
793         Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", orNodeId,
794             PHTNC_MEDIA)).getBytes(Charset.forName("UTF-8"))).toString());
795         // Names
796         Name nodeNames =  new NameBuilder().setValueName("roadm node name")
797             .setValue(String.join("+", orNodeId, PHTNC_MEDIA)).build();
798         // Protocol Layer
799         List<LayerProtocolName> layerProtocols = Arrays.asList(LayerProtocolName.PHOTONICMEDIA);
800         // Empty random creation of mandatory fields for avoiding errors....
801         CostCharacteristic costCharacteristic = new CostCharacteristicBuilder()
802             .setCostAlgorithm("Restricted Shortest Path - RSP")
803             .setCostName("HOP_COUNT")
804             .setCostValue("12345678")
805             .build();
806         LatencyCharacteristic latencyCharacteristic = new LatencyCharacteristicBuilder()
807             .setFixedLatencyCharacteristic("12345678")
808             .setQueingLatencyCharacteristic("12345678")
809             .setJitterCharacteristic("12345678")
810             .setWanderCharacteristic("12345678")
811             .setTrafficPropertyName("FIXED_LATENCY")
812             .build();
813         return new NodeBuilder()
814             .setUuid(nodeUuid)
815             .setName(Map.of(nodeNames.key(), nodeNames))
816             .setLayerProtocolName(layerProtocols)
817             .setAdministrativeState(AdministrativeState.UNLOCKED)
818             .setOperationalState(OperationalState.ENABLED)
819             .setLifecycleState(LifecycleState.INSTALLED)
820             .setOwnedNodeEdgePoint(oneplist)
821             .setNodeRuleGroup(createNodeRuleGroupForRdmNode(orNodeId, nodeUuid, oneplist.values()))
822             .setCostCharacteristic(Map.of(costCharacteristic.key(), costCharacteristic))
823             .setLatencyCharacteristic(Map.of(latencyCharacteristic.key(), latencyCharacteristic))
824             .setErrorCharacteristic("error")
825             .setLossCharacteristic("loss")
826             .setRepeatDeliveryCharacteristic("repeat delivery")
827             .setDeliveryOrderCharacteristic("delivery order")
828             .setUnavailableTimeCharacteristic("unavailable time")
829             .setServerIntegrityProcessCharacteristic("server integrity process")
830             .build();
831     }
832
833     private Map<NodeRuleGroupKey, NodeRuleGroup> createNodeRuleGroupForRdmNode(String orNodeId, Uuid nodeUuid,
834                                                                                Collection<OwnedNodeEdgePoint> onepl) {
835         Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.NodeEdgePointKey,
836                 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.NodeEdgePoint>
837                 nepMap = new HashMap<>();
838         for (OwnedNodeEdgePoint onep : onepl) {
839             org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.NodeEdgePoint
840                     nep = new org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group
841                     .NodeEdgePointBuilder()
842                     .setTopologyUuid(tapiTopoUuid)
843                     .setNodeUuid(nodeUuid)
844                     .setNodeEdgePointUuid(onep.key().getUuid())
845                     .build();
846             nepMap.put(nep.key(), nep);
847         }
848         Map<NodeRuleGroupKey, NodeRuleGroup> nodeRuleGroupMap = new HashMap<>();
849         Map<RuleKey, Rule> ruleList = new HashMap<>();
850         Rule rule = new RuleBuilder()
851                 .setLocalId("forward")
852                 .setForwardingRule(ForwardingRule.MAYFORWARDACROSSGROUP)
853                 .setRuleType(RuleType.FORWARDING)
854                 .build();
855         ruleList.put(rule.key(), rule);
856         NodeRuleGroup nodeRuleGroup = new NodeRuleGroupBuilder()
857                 .setUuid(new Uuid(UUID.nameUUIDFromBytes((orNodeId + " node rule group")
858                         .getBytes(Charset.forName("UTF-8"))).toString()))
859                 .setRule(ruleList)
860                 .setNodeEdgePoint(nepMap)
861                 .build();
862         nodeRuleGroupMap.put(nodeRuleGroup.key(), nodeRuleGroup);
863         return nodeRuleGroupMap;
864     }
865
866     private Map<LinkKey, Link> createTapiTransitionalLinks(String nodeId, List<Mapping> xpdrNetMaps, Uuid nodeUuidDsr,
867                                                            Uuid nodeUuidOtsi) {
868         Map<LinkKey, Link> linkMap = new HashMap<>();
869         for (Mapping mapping : xpdrNetMaps) {
870             Map<NodeEdgePointKey, NodeEdgePoint> nepList = new HashMap<>();
871             String sourceKey = String.join("+", nodeId, I_ODU, mapping.getLogicalConnectionPoint());
872             Uuid sourceUuidTp = new Uuid(UUID.nameUUIDFromBytes(
873                     (String.join("+", nodeId, I_ODU, mapping.getLogicalConnectionPoint()))
874                             .getBytes(Charset.forName("UTF-8"))).toString());
875             String destKey = String.join("+", nodeId, I_OTSI, mapping.getLogicalConnectionPoint());
876             Uuid destUuidTp = new Uuid(UUID.nameUUIDFromBytes(
877                     (String.join("+", nodeId, I_OTSI, mapping.getLogicalConnectionPoint()))
878                             .getBytes(Charset.forName("UTF-8"))).toString());
879             NodeEdgePoint sourceNep = new NodeEdgePointBuilder()
880                     .setTopologyUuid(this.tapiTopoUuid)
881                     .setNodeUuid(nodeUuidDsr)
882                     .setNodeEdgePointUuid(sourceUuidTp)
883                     .build();
884             nepList.put(sourceNep.key(), sourceNep);
885             NodeEdgePoint destNep = new NodeEdgePointBuilder()
886                     .setTopologyUuid(this.tapiTopoUuid)
887                     .setNodeUuid(nodeUuidOtsi)
888                     .setNodeEdgePointUuid(destUuidTp)
889                     .build();
890             nepList.put(destNep.key(), destNep);
891             Name linkName = new NameBuilder().setValueName("transitional link name")
892                     .setValue(String.join("--",nodeId, sourceKey, destKey))
893                     .build();
894             CostCharacteristic costCharacteristic = new CostCharacteristicBuilder()
895                 .setCostAlgorithm("Restricted Shortest Path - RSP")
896                 .setCostName("HOP_COUNT")
897                 .setCostValue("12345678")
898                 .build();
899             LatencyCharacteristic latencyCharacteristic = new LatencyCharacteristicBuilder()
900                 .setFixedLatencyCharacteristic("12345678")
901                 .setQueingLatencyCharacteristic("12345678")
902                 .setJitterCharacteristic("12345678")
903                 .setWanderCharacteristic("12345678")
904                 .setTrafficPropertyName("FIXED_LATENCY")
905                 .build();
906             RiskCharacteristic riskCharacteristic = new RiskCharacteristicBuilder()
907                 .setRiskCharacteristicName("risk characteristic")
908                 .setRiskIdentifierList(List.of("risk identifier1", "risk identifier2"))
909                 .build();
910             ValidationMechanism validationMechanism = new ValidationMechanismBuilder()
911                 .setValidationMechanism("validation mechanism")
912                 .setValidationRobustness("validation robustness")
913                 .setLayerProtocolAdjacencyValidated("layer protocol adjacency")
914                 .build();
915             Link transiLink = new LinkBuilder()
916                 .setUuid(new Uuid(
917                     UUID.nameUUIDFromBytes((String.join("--", nodeId, sourceKey, destKey))
918                         .getBytes(Charset.forName("UTF-8")))
919                         .toString()))
920                 .setName(Map.of(linkName.key(), linkName))
921                 .setTransitionedLayerProtocolName(Arrays.asList(LayerProtocolName.ODU.getName(),
922                     LayerProtocolName.PHOTONICMEDIA.getName()))
923                 .setNodeEdgePoint(nepList)
924                 .setLayerProtocolName(Arrays.asList(LayerProtocolName.PHOTONICMEDIA, LayerProtocolName.ODU))
925                 .setDirection(ForwardingDirection.BIDIRECTIONAL)
926                 .setAvailableCapacity(new AvailableCapacityBuilder().setTotalSize(
927                     new TotalSizeBuilder().setUnit(CapacityUnit.GBPS).setValue(Uint64.valueOf(100)).build())
928                     .build())
929                 .setResilienceType(new ResilienceTypeBuilder().setProtectionType(ProtectionType.NOPROTECTON)
930                     .setRestorationPolicy(RestorationPolicy.NA)
931                     .build())
932                 .setAdministrativeState(transformAdminState(mapping.getPortAdminState()))
933                 .setOperationalState(transformOperState(mapping.getPortOperState()))
934                 .setLifecycleState(LifecycleState.INSTALLED)
935                 .setTotalPotentialCapacity(new TotalPotentialCapacityBuilder().setTotalSize(
936                     new TotalSizeBuilder().setUnit(CapacityUnit.GBPS).setValue(Uint64.valueOf(100)).build())
937                     .build())
938                 .setCostCharacteristic(Map.of(costCharacteristic.key(), costCharacteristic))
939                 .setLatencyCharacteristic(Map.of(latencyCharacteristic.key(), latencyCharacteristic))
940                 .setRiskCharacteristic(Map.of(riskCharacteristic.key(), riskCharacteristic))
941                 .setErrorCharacteristic("error")
942                 .setLossCharacteristic("loss")
943                 .setRepeatDeliveryCharacteristic("repeat delivery")
944                 .setDeliveryOrderCharacteristic("delivery order")
945                 .setUnavailableTimeCharacteristic("unavailable time")
946                 .setServerIntegrityProcessCharacteristic("server integrity process")
947                 .setValidationMechanism(Map.of(validationMechanism.key(), validationMechanism))
948                 .build();
949             linkMap.put(transiLink.key(), transiLink);
950         }
951         // return a map of links and then we can do merge the corresponding link map into the topology context
952         return linkMap;
953     }
954
955     private OduSwitchingPools createTpdrSwitchPool() {
956         return new OduSwitchingPoolsBuilder().build();
957     }
958
959     private OduSwitchingPools createSwtchSwitchPool(List<Mapping> xpdrClMaps, List<Mapping> xpdrNetMaps,
960                                                     Integer xpdrNb) {
961         List<TpId> tpl = new ArrayList<>();
962         TpId tpId = null;
963         for (int i = 1; i <= xpdrClMaps.size(); i++) {
964             tpId = new TpId("XPDR" + xpdrNb + CLIENT + i);
965             tpl.add(tpId);
966         }
967         for (int i = 1; i <= xpdrNetMaps.size(); i++) {
968             tpId = new TpId("XPDR" + xpdrNb + NETWORK + i);
969             tpl.add(tpId);
970         }
971         Map<NonBlockingListKey, NonBlockingList> nbMap = new HashMap<>();
972         NonBlockingList nbl = new NonBlockingListBuilder()
973                 .setNblNumber(Uint16.valueOf(1))
974                 .setTpList(tpl)
975                 .build();
976         nbMap.put(nbl.key(),nbl);
977
978         return new OduSwitchingPoolsBuilder()
979                 .setSwitchingPoolNumber(Uint16.valueOf(1))
980                 .setSwitchingPoolType(SwitchingPoolTypes.NonBlocking)
981                 .setNonBlockingList(nbMap)
982                 .build();
983     }
984
985     private OduSwitchingPools createMuxSwitchPool(List<Mapping> xpdrClMaps, List<Mapping> xpdrNetMaps, Integer xpdrNb) {
986         Map<NonBlockingListKey, NonBlockingList> nbMap = new HashMap<>();
987         for (int i = 1; i <= xpdrClMaps.size(); i++) {
988             List<TpId> tpList = new ArrayList<>();
989             TpId tpId = new TpId("XPDR" + xpdrNb + CLIENT + i);
990             tpList.add(tpId);
991             tpId = new TpId("XPDR" + xpdrNb + "-NETWORK1");
992             tpList.add(tpId);
993             NonBlockingList nbl = new NonBlockingListBuilder()
994                     .setNblNumber(Uint16.valueOf(i))
995                     .setTpList(tpList)
996                     .setAvailableInterconnectBandwidth(Uint32.valueOf(xpdrNetMaps.size() * 10L))
997                     .setInterconnectBandwidthUnit(Uint32.valueOf(1000000000))
998                     .build();
999             nbMap.put(nbl.key(),nbl);
1000         }
1001         return new OduSwitchingPoolsBuilder()
1002                 .setSwitchingPoolNumber(Uint16.valueOf(1))
1003                 .setSwitchingPoolType(SwitchingPoolTypes.NonBlocking)
1004                 .setNonBlockingList(nbMap)
1005                 .build();
1006     }
1007
1008     private Map<NodeRuleGroupKey, NodeRuleGroup> createNodeRuleGroupForOtsiNode(String nodeId,
1009                                                                                 List<Mapping> xpdrNetMaps,
1010                                                                                 Map<RuleKey, Rule> ruleList) {
1011         Map<NodeRuleGroupKey, NodeRuleGroup> nodeRuleGroupMap = new HashMap<>();
1012         // create NodeRuleGroup
1013         int count = 1;
1014         for (Mapping tpMapping : xpdrNetMaps) {
1015             Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.NodeEdgePointKey,
1016                 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.NodeEdgePoint>
1017                     nepList = new HashMap<>();
1018             org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group
1019                     .NodeEdgePoint inep = new org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210
1020                     .node.rule.group.NodeEdgePointBuilder()
1021                     .setTopologyUuid(tapiTopoUuid)
1022                     .setNodeUuid(new Uuid(UUID.nameUUIDFromBytes(
1023                             (String.join("+", nodeId, OTSI)).getBytes(Charset.forName("UTF-8")))
1024                             .toString()))
1025                     .setNodeEdgePointUuid(new Uuid(UUID.nameUUIDFromBytes(
1026                             (String.join("+", nodeId, I_OTSI, tpMapping.getLogicalConnectionPoint()))
1027                                     .getBytes(Charset.forName("UTF-8"))).toString()))
1028                     .build();
1029             org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group
1030                     .NodeEdgePoint enep = new org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210
1031                     .node.rule.group.NodeEdgePointBuilder()
1032                     .setTopologyUuid(tapiTopoUuid)
1033                     .setNodeUuid(new Uuid(UUID.nameUUIDFromBytes(
1034                             (String.join("+", nodeId, OTSI)).getBytes(Charset.forName("UTF-8")))
1035                             .toString()))
1036                     .setNodeEdgePointUuid(new Uuid(UUID.nameUUIDFromBytes(
1037                             (String.join("+", nodeId, E_OTSI, tpMapping.getLogicalConnectionPoint()))
1038                                     .getBytes(Charset.forName("UTF-8"))).toString()))
1039                     .build();
1040             nepList.put(inep.key(), inep);
1041             nepList.put(enep.key(), enep);
1042             // Empty random creation of mandatory fields for avoiding errors....
1043             CostCharacteristic costCharacteristic = new CostCharacteristicBuilder()
1044                 .setCostAlgorithm("Restricted Shortest Path - RSP")
1045                 .setCostName("HOP_COUNT")
1046                 .setCostValue("12345678")
1047                 .build();
1048             LatencyCharacteristic latencyCharacteristic = new LatencyCharacteristicBuilder()
1049                 .setFixedLatencyCharacteristic("12345678")
1050                 .setQueingLatencyCharacteristic("12345678")
1051                 .setJitterCharacteristic("12345678")
1052                 .setWanderCharacteristic("12345678")
1053                 .setTrafficPropertyName("FIXED_LATENCY")
1054                 .build();
1055             RiskCharacteristic riskCharacteristic = new RiskCharacteristicBuilder()
1056                 .setRiskCharacteristicName("risk characteristic")
1057                 .setRiskIdentifierList(List.of("risk identifier1", "risk identifier2"))
1058                 .build();
1059             NodeRuleGroup nodeRuleGroup = new NodeRuleGroupBuilder()
1060                 .setUuid(new Uuid(
1061                     UUID.nameUUIDFromBytes(("otsi node rule group " + count).getBytes(Charset.forName("UTF-8")))
1062                         .toString()))
1063                 .setRule(ruleList)
1064                 .setNodeEdgePoint(nepList)
1065                 .setRiskCharacteristic(Map.of(riskCharacteristic.key(), riskCharacteristic))
1066                 .setCostCharacteristic(Map.of(costCharacteristic.key(), costCharacteristic))
1067                 .setLatencyCharacteristic(Map.of(latencyCharacteristic.key(), latencyCharacteristic))
1068                 .build();
1069             nodeRuleGroupMap.put(nodeRuleGroup.key(), nodeRuleGroup);
1070             count++;
1071         }
1072         return nodeRuleGroupMap;
1073     }
1074
1075     private Map<NodeRuleGroupKey, NodeRuleGroup> createNodeRuleGroupForDsrNode(String nodeId,
1076                                                                                OduSwitchingPools oorOduSwitchingPool,
1077                                                                                Map<RuleKey, Rule> ruleList,
1078                                                                                Map<OwnedNodeEdgePointKey,
1079                                                                                        OwnedNodeEdgePoint> onepl) {
1080         // create NodeRuleGroup
1081         if (oorOduSwitchingPool == null) {
1082             LOG.info("TPDR node --> no switching pool");
1083             return new HashMap<>();
1084         }
1085         LOG.info("ONEPL = {}", onepl.values());
1086         Map<NodeRuleGroupKey, NodeRuleGroup> nodeRuleGroupMap = new HashMap<>();
1087         int count = 1;
1088         for (NonBlockingList nbl : oorOduSwitchingPool.nonnullNonBlockingList().values()) {
1089             LOG.info("Non blocking list = {}", nbl);
1090             Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.NodeEdgePointKey,
1091                 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.NodeEdgePoint>
1092                     nepList = new HashMap<>();
1093             for (TpId tp : nbl.getTpList()) {
1094                 LOG.info("EDOU TP = {}", String.join("+", nodeId, E_ODU, tp.getValue()));
1095                 LOG.info("DSR TP = {}", String.join("+", nodeId, DSR, tp.getValue()));
1096                 Uuid tpUuid = new Uuid(UUID.nameUUIDFromBytes(
1097                         (String.join("+", nodeId, E_ODU, tp.getValue())).getBytes(Charset.forName("UTF-8")))
1098                         .toString());
1099                 Uuid tp1Uuid = new Uuid(UUID.nameUUIDFromBytes(
1100                     (String.join("+", nodeId, DSR, tp.getValue())).getBytes(Charset.forName("UTF-8")))
1101                     .toString());
1102                 if (onepl.containsKey(new OwnedNodeEdgePointKey(tpUuid))
1103                         || onepl.containsKey(new OwnedNodeEdgePointKey(tp1Uuid))) {
1104                     org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.NodeEdgePoint
1105                         nep = new org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group
1106                             .NodeEdgePointBuilder()
1107                             .setTopologyUuid(tapiTopoUuid)
1108                             .setNodeUuid(new Uuid(UUID.nameUUIDFromBytes(
1109                                     (String.join("+", nodeId, DSR)).getBytes(Charset.forName("UTF-8")))
1110                                     .toString()))
1111                             .setNodeEdgePointUuid((tp.getValue().contains("CLIENT")) ? tp1Uuid : tpUuid)
1112                             .build();
1113                     nepList.put(nep.key(), nep);
1114                 }
1115             }
1116             // Empty random creation of mandatory fields for avoiding errors....
1117             CostCharacteristic costCharacteristic = new CostCharacteristicBuilder()
1118                 .setCostAlgorithm("Restricted Shortest Path - RSP")
1119                 .setCostName("HOP_COUNT")
1120                 .setCostValue("12345678")
1121                 .build();
1122             LatencyCharacteristic latencyCharacteristic = new LatencyCharacteristicBuilder()
1123                 .setFixedLatencyCharacteristic("12345678")
1124                 .setQueingLatencyCharacteristic("12345678")
1125                 .setJitterCharacteristic("12345678")
1126                 .setWanderCharacteristic("12345678")
1127                 .setTrafficPropertyName("FIXED_LATENCY")
1128                 .build();
1129             RiskCharacteristic riskCharacteristic = new RiskCharacteristicBuilder()
1130                 .setRiskCharacteristicName("risk characteristic")
1131                 .setRiskIdentifierList(List.of("risk identifier1", "risk identifier2"))
1132                 .build();
1133             NodeRuleGroup nodeRuleGroup = new NodeRuleGroupBuilder()
1134                 .setUuid(new Uuid(
1135                     UUID.nameUUIDFromBytes(("dsr node rule group " + count).getBytes(Charset.forName("UTF-8")))
1136                         .toString()))
1137                 .setRule(ruleList)
1138                 .setNodeEdgePoint(nepList)
1139                 .setRiskCharacteristic(Map.of(riskCharacteristic.key(), riskCharacteristic))
1140                 .setCostCharacteristic(Map.of(costCharacteristic.key(), costCharacteristic))
1141                 .setLatencyCharacteristic(Map.of(latencyCharacteristic.key(), latencyCharacteristic))
1142                 .build();
1143             nodeRuleGroupMap.put(nodeRuleGroup.key(), nodeRuleGroup);
1144             count++;
1145         }
1146         return nodeRuleGroupMap;
1147     }
1148
1149     private List<Class<? extends LAYERPROTOCOLQUALIFIER>> createSupportedLayerProtocolQualifier(
1150             List<Class<? extends SupportedIfCapability>> sicList, LayerProtocolName lpn) {
1151         if (sicList == null) {
1152             return List.of(PHOTONICLAYERQUALIFIEROMS.class);
1153         }
1154         Map<SupportedInterfaceCapabilityKey, SupportedInterfaceCapability> supIfMap = new HashMap<>();
1155         LOG.info("SIC list = {}", sicList);
1156         for (Class<? extends SupportedIfCapability> supInterCapa : sicList) {
1157             SupportedInterfaceCapability supIfCapa = new SupportedInterfaceCapabilityBuilder()
1158                     .withKey(new SupportedInterfaceCapabilityKey(convertSupIfCapa(supInterCapa)))
1159                     .setIfCapType(convertSupIfCapa(supInterCapa))
1160                     .build();
1161             supIfMap.put(supIfCapa.key(), supIfCapa);
1162         }
1163         List<Class<? extends LAYERPROTOCOLQUALIFIER>> sclpqList = new ArrayList<>();
1164         for (SupportedInterfaceCapability sic : supIfMap.values()) {
1165             switch (lpn.getName()) {
1166                 case "DSR":
1167                 case "ODU":
1168                     switch (sic.getIfCapType().getSimpleName()) {
1169                         // TODO: it may be needed to add more cases clauses if the interface capabilities of a
1170                         //  port are extended in the config file
1171                         case "If1GEODU0":
1172                             sclpqList.add(ODUTYPEODU0.class);
1173                             sclpqList.add(DIGITALSIGNALTYPEGigE.class);
1174                             break;
1175                         case "If10GEODU2e":
1176                             sclpqList.add(ODUTYPEODU2E.class);
1177                             sclpqList.add(DIGITALSIGNALTYPE10GigELAN.class);
1178                             break;
1179                         case "If10GEODU2":
1180                             sclpqList.add(ODUTYPEODU2.class);
1181                             sclpqList.add(DIGITALSIGNALTYPE10GigELAN.class);
1182                             break;
1183                         case "If10GE":
1184                             sclpqList.add(DIGITALSIGNALTYPE10GigELAN.class);
1185                             break;
1186                         case "If100GEODU4":
1187                             sclpqList.add(DIGITALSIGNALTYPE100GigE.class);
1188                             sclpqList.add(ODUTYPEODU4.class);
1189                             break;
1190                         case "If100GE":
1191                             sclpqList.add(DIGITALSIGNALTYPE100GigE.class);
1192                             break;
1193                         case "IfOCHOTU4ODU4":
1194                         case "IfOCH":
1195                             sclpqList.add(ODUTYPEODU4.class);
1196                             break;
1197                         default:
1198                             LOG.error("IfCapability type not managed");
1199                             break;
1200                     }
1201                     break;
1202                 case "PHOTONIC_MEDIA":
1203                     if (sic.getIfCapType().getSimpleName().equals("IfOCHOTU4ODU4")
1204                         || sic.getIfCapType().getSimpleName().equals("IfOCH")) {
1205                         sclpqList.add(PHOTONICLAYERQUALIFIEROTSi.class);
1206                         sclpqList.add(PHOTONICLAYERQUALIFIEROMS.class);
1207                     }
1208                     break;
1209                 default:
1210                     LOG.error("Layer Protocol Name is unknown {}", lpn.getName());
1211                     break;
1212             }
1213         }
1214         return sclpqList;
1215     }
1216
1217     private static Class<? extends SupportedIfCapability> convertSupIfCapa(Class<? extends
1218             SupportedIfCapability> ifCapType) {
1219         LOG.info("Interface Capability type = {}", ifCapType.getSimpleName());
1220         switch (ifCapType.getSimpleName()) {
1221             case "If100GEODU4":
1222                 return If100GEODU4.class;
1223             case "IfOCHOTU4ODU4":
1224                 return IfOCHOTU4ODU4.class;
1225             case "If1GEODU0":
1226                 return If1GEODU0.class;
1227             case "If10GEODU2e":
1228                 return If10GEODU2e.class;
1229             case "If10GEODU2":
1230                 return If10GEODU2.class;
1231             case "If100GE":
1232                 return If100GE.class;
1233             case "If10GE":
1234                 return If10GE.class;
1235             case "If1GE":
1236                 return If1GE.class;
1237             case "IfOCH":
1238                 return IfOCH.class;
1239             default:
1240                 return null;
1241         }
1242     }
1243
1244     private void mergeNodeinTopology(Map<NodeKey, Node> nodeMap) {
1245         // TODO is this merge correct? Should we just merge topology by changing the nodes map??
1246         // TODO: verify this is correct. Should we identify the context IID with the context UUID??
1247         LOG.info("Creating tapi node in TAPI topology context");
1248         InstanceIdentifier<Topology> topoIID = InstanceIdentifier.builder(Context.class)
1249             .augmentation(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.Context1.class)
1250             .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.context.TopologyContext.class)
1251             .child(Topology.class, new TopologyKey(tapiTopoUuid))
1252             .build();
1253
1254         Topology topology = new TopologyBuilder().setUuid(tapiTopoUuid).setNode(nodeMap).build();
1255
1256         // merge in datastore
1257         this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, topoIID,
1258                 topology);
1259         try {
1260             this.networkTransactionService.commit().get();
1261         } catch (InterruptedException | ExecutionException e) {
1262             LOG.error("Error populating TAPI topology: ", e);
1263         }
1264         LOG.info("Node added succesfully.");
1265     }
1266
1267     private void mergeLinkinTopology(Map<LinkKey, Link> linkMap) {
1268         // TODO is this merge correct? Should we just merge topology by changing the nodes map??
1269         // TODO: verify this is correct. Should we identify the context IID with the context UUID??
1270         LOG.info("Creating tapi node in TAPI topology context");
1271         InstanceIdentifier<Topology> topoIID = InstanceIdentifier.builder(Context.class)
1272                 .augmentation(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.Context1.class)
1273                 .child(org.opendaylight.yang.gen.v1.urn
1274                         .onf.otcc.yang.tapi.topology.rev181210.context.TopologyContext.class)
1275                 .child(Topology.class, new TopologyKey(tapiTopoUuid))
1276                 .build();
1277
1278         Topology topology = new TopologyBuilder().setUuid(tapiTopoUuid).setLink(linkMap).build();
1279
1280         // merge in datastore
1281         this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, topoIID,
1282                 topology);
1283         try {
1284             this.networkTransactionService.commit().get();
1285         } catch (InterruptedException | ExecutionException e) {
1286             LOG.error("Error populating TAPI topology: ", e);
1287         }
1288         LOG.info("Roadm Link added succesfully.");
1289     }
1290
1291     private void mergeSipsinContext(Map<ServiceInterfacePointKey, ServiceInterfacePoint> sips) {
1292         // TODO is this merge correct? Should we just merge topology by changing the nodes map??
1293         // TODO: verify this is correct. Should we identify the context IID with the context UUID??
1294         try {
1295             ContextBuilder contextBuilder = new ContextBuilder();
1296             contextBuilder.setServiceInterfacePoint(sips);
1297             InstanceIdentifier<Context> contextIID = InstanceIdentifier.builder(Context.class).build();
1298             // merge in datastore
1299             this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, contextIID,
1300                     contextBuilder.build());
1301             this.networkTransactionService.commit().get();
1302             LOG.info("TAPI SIPs merged successfully.");
1303         } catch (InterruptedException | ExecutionException e) {
1304             LOG.error("Failed to merge TAPI Sips", e);
1305         }
1306     }
1307
1308     private void deleteLinkFromTopo(Uuid linkUuid) {
1309         // TODO: check if this IID is correct
1310         try {
1311             InstanceIdentifier<Link> linkIID = InstanceIdentifier.builder(Context.class)
1312                 .augmentation(Context1.class).child(TopologyContext.class).child(Topology.class,
1313                     new TopologyKey(tapiTopoUuid)).child(Link.class, new LinkKey(linkUuid)).build();
1314             this.networkTransactionService.delete(LogicalDatastoreType.OPERATIONAL, linkIID);
1315             this.networkTransactionService.commit().get();
1316             LOG.info("TAPI link deleted successfully.");
1317         } catch (InterruptedException | ExecutionException e) {
1318             LOG.error("Failed to delete TAPI link", e);
1319         }
1320     }
1321
1322     private void deleteNodeFromTopo(Uuid nodeUuid) {
1323         // TODO: check if this IID is correct
1324         try {
1325             InstanceIdentifier<Node> nodeIDD = InstanceIdentifier.builder(Context.class)
1326                 .augmentation(Context1.class).child(TopologyContext.class).child(Topology.class,
1327                     new TopologyKey(tapiTopoUuid)).child(Node.class, new NodeKey(nodeUuid)).build();
1328             this.networkTransactionService.delete(LogicalDatastoreType.OPERATIONAL, nodeIDD);
1329             this.networkTransactionService.commit().get();
1330             LOG.info("TAPI Node deleted successfully.");
1331         } catch (InterruptedException | ExecutionException e) {
1332             LOG.error("Failed to delete TAPI Node", e);
1333         }
1334     }
1335
1336     private void deleteSipFromTopo(Uuid sipUuid) {
1337         // TODO: check if this IID is correct
1338         try {
1339             InstanceIdentifier<ServiceInterfacePoint> sipIID = InstanceIdentifier.builder(Context.class)
1340                     .child(ServiceInterfacePoint.class, new ServiceInterfacePointKey(sipUuid)).build();
1341             this.networkTransactionService.delete(LogicalDatastoreType.OPERATIONAL, sipIID);
1342             this.networkTransactionService.commit().get();
1343             LOG.info("TAPI SIP deleted successfully.");
1344         } catch (InterruptedException | ExecutionException e) {
1345             LOG.error("Failed to delete TAPI SIP", e);
1346         }
1347     }
1348
1349     private void updateConnectivityServicesState(Uuid sipUuid, String nodeId) {
1350         // TODO: check if this IID is correct
1351         InstanceIdentifier<ConnectivityContext> connectivitycontextIID = InstanceIdentifier.builder(Context.class)
1352                 .augmentation(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.Context1.class)
1353                 .child(ConnectivityContext.class)
1354                 .build();
1355         ConnectivityContext connContext = null;
1356         try {
1357             Optional<ConnectivityContext> optConnContext =
1358                     this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connectivitycontextIID)
1359                             .get();
1360             if (!optConnContext.isPresent()) {
1361                 LOG.error("Couldnt retrieve connectivity context from datastore");
1362                 return;
1363             }
1364             connContext = optConnContext.get();
1365         } catch (InterruptedException | ExecutionException e) {
1366             LOG.error("Couldnt read connectivity context from datastore", e);
1367         }
1368         if (connContext == null) {
1369             LOG.error("Connectivity context is empty");
1370             return;
1371         }
1372         // Loop through services, check if the endpoint uuid is equal to the sip.
1373         // If so update state.
1374         Map<ConnectivityServiceKey, ConnectivityService> connServMap = connContext.getConnectivityService();
1375         Map<ConnectionKey, Connection> connMap = connContext.getConnection();
1376         if (connServMap != null) {
1377             for (ConnectivityService service:connServMap.values()) {
1378                 Map<EndPointKey, EndPoint> serviceEndPoints = service.getEndPoint();
1379                 if (serviceEndPoints.values().stream().anyMatch(endPoint -> endPoint.getServiceInterfacePoint()
1380                     .getServiceInterfacePointUuid().equals(sipUuid))) {
1381                     LOG.info("Service using SIP of node {} identified. Update state of service", nodeId);
1382                     ConnectivityService updService = new ConnectivityServiceBuilder(service)
1383                         .setAdministrativeState(AdministrativeState.LOCKED)
1384                         .setOperationalState(OperationalState.DISABLED)
1385                         .setLifecycleState(LifecycleState.PENDINGREMOVAL)
1386                         .build();
1387                     updateConnectivityService(updService);
1388                 }
1389             }
1390         }
1391         // Update state of connections
1392         if (connMap != null) {
1393             for (Connection connection:connMap.values()) {
1394                 if (connection.getName().values().stream().anyMatch(name -> name.getValue().contains(nodeId))) {
1395                     Connection updConn = new ConnectionBuilder(connection)
1396                         .setLifecycleState(LifecycleState.PENDINGREMOVAL)
1397                         .setOperationalState(OperationalState.DISABLED)
1398                         .build();
1399                     updateConnection(updConn);
1400                 }
1401             }
1402         }
1403     }
1404
1405     private void updateConnection(Connection updConn) {
1406         // TODO: check if this IID is correct
1407         InstanceIdentifier<Connection> connectionIID = InstanceIdentifier.builder(Context.class)
1408                 .augmentation(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.Context1.class)
1409                 .child(ConnectivityContext.class).child(Connection.class,
1410                         new ConnectionKey(updConn.getUuid())).build();
1411         this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, connectionIID, updConn);
1412         try {
1413             this.networkTransactionService.commit().get();
1414         } catch (InterruptedException | ExecutionException e) {
1415             LOG.error("Error committing into datastore", e);
1416         }
1417     }
1418
1419     private void updateConnectivityService(ConnectivityService updService) {
1420         // TODO: check if this IID is correct
1421         InstanceIdentifier<ConnectivityService> connectivityserviceIID = InstanceIdentifier.builder(Context.class)
1422                 .augmentation(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.Context1.class)
1423                 .child(ConnectivityContext.class).child(ConnectivityService.class,
1424                         new ConnectivityServiceKey(updService.getUuid())).build();
1425         this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, connectivityserviceIID, updService);
1426         try {
1427             this.networkTransactionService.commit().get();
1428         } catch (InterruptedException | ExecutionException e) {
1429             LOG.error("Error committing into datastore", e);
1430         }
1431     }
1432
1433 }