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