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