2 * Copyright © 2021 Nokia, Inc. and others. All rights reserved.
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
8 package org.opendaylight.transportpce.tapi.listeners;
10 import java.nio.charset.StandardCharsets;
11 import java.time.OffsetDateTime;
12 import java.time.ZoneOffset;
13 import java.time.format.DateTimeFormatter;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.Collections;
17 import java.util.HashMap;
18 import java.util.List;
20 import java.util.Objects;
21 import java.util.Optional;
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.network.NetworkTransactionService;
28 import org.opendaylight.transportpce.tapi.TapiStringConstants;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State;
30 import org.opendaylight.yang.gen.v1.nbi.notifications.rev211013.PublishTapiNotificationService;
31 import org.opendaylight.yang.gen.v1.nbi.notifications.rev211013.PublishTapiNotificationServiceBuilder;
32 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.AdministrativeState;
33 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.Context;
34 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.DateAndTime;
35 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.LayerProtocolName;
36 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.OperationalState;
37 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.Uuid;
38 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.Name;
39 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.NameKey;
40 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.OwnedNodeEdgePoint1;
41 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connection.LowerConnection;
42 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection;
43 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionBuilder;
44 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey;
45 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityService;
46 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityServiceBuilder;
47 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityServiceKey;
48 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext;
49 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.NameAndValueChange;
50 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.Notification;
51 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.NotificationType;
52 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.ObjectType;
53 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.TapiNotificationListener;
54 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.notification.ChangedAttributes;
55 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.notification.ChangedAttributesBuilder;
56 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.notification.ChangedAttributesKey;
57 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.notification.TargetObjectName;
58 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.notification.TargetObjectNameBuilder;
59 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.notification.TargetObjectNameKey;
60 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.Context1;
61 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.NodeEdgePointRef;
62 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.context.TopologyContext;
63 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePoint;
64 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePointKey;
65 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node;
66 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.NodeKey;
67 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.Topology;
68 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.TopologyKey;
69 import org.opendaylight.yangtools.yang.binding.EnumTypeObject;
70 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
71 import org.slf4j.Logger;
72 import org.slf4j.LoggerFactory;
74 public class TapiNetworkModelListenerImpl implements TapiNotificationListener {
76 private static final Logger LOG = LoggerFactory.getLogger(TapiNetworkModelListenerImpl.class);
77 private final NetworkTransactionService networkTransactionService;
78 private final List<ConnectivityService> connectivityServiceChanges = new ArrayList<>();
79 private final Uuid tapiTopoUuid = new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER
80 .getBytes(StandardCharsets.UTF_8)).toString());
81 private final List<LayerProtocolName> orderedServiceLayerList;
82 private final NotificationPublishService notificationPublishService;
84 public TapiNetworkModelListenerImpl(NetworkTransactionService networkTransactionService,
85 NotificationPublishService notificationPublishService) {
86 this.networkTransactionService = networkTransactionService;
87 this.orderedServiceLayerList = List.of(LayerProtocolName.PHOTONICMEDIA, LayerProtocolName.ODU,
88 LayerProtocolName.DSR, LayerProtocolName.ETH);
89 this.notificationPublishService = notificationPublishService;
93 public void onNotification(Notification notification) {
94 LOG.info("Received network model notification {}", notification);
95 if (notification.getNotificationType() == NotificationType.ATTRIBUTEVALUECHANGE
96 && notification.getTargetObjectType() == ObjectType.NODEEDGEPOINT) {
97 if (notification.getChangedAttributes() == null) {
100 // TODO: need to re-think this to update first the connections from roadm to roadm and then the others
101 updateConnections(notification.getChangedAttributes().keySet().stream()
102 .map(changedAttributesKey -> new Uuid(changedAttributesKey.getValueName()))
103 .collect(Collectors.toList()),
104 notification.getChangedAttributes().values().stream()
105 .map(NameAndValueChange::getNewValue)
106 .collect(Collectors.toList()));
107 updateConnectivityServices();
108 // todo set attributes
109 for (ConnectivityService connService : this.connectivityServiceChanges) {
110 sendNbiNotification(createNbiNotification(connService));
115 private PublishTapiNotificationService createNbiNotification(ConnectivityService connService) {
116 if (connService == null) {
117 LOG.error("ConnService is null");
120 Map<ChangedAttributesKey, ChangedAttributes> changedStates = new HashMap<>();
121 changedStates.put(new ChangedAttributesKey("administrativeState"),
122 new ChangedAttributesBuilder()
123 .setNewValue(connService.getAdministrativeState().getName())
124 .setOldValue(connService.getAdministrativeState().equals(AdministrativeState.UNLOCKED)
125 ? AdministrativeState.LOCKED.getName() : AdministrativeState.UNLOCKED.getName())
126 .setValueName("administrativeState").build());
127 changedStates.put(new ChangedAttributesKey("operationalState"),
128 new ChangedAttributesBuilder()
129 .setNewValue(connService.getOperationalState().getName())
130 .setOldValue(connService.getOperationalState().equals(OperationalState.ENABLED)
131 ? OperationalState.DISABLED.getName() : OperationalState.ENABLED.getName())
132 .setValueName("operationalState").build());
133 DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssxxx");
134 OffsetDateTime offsetDateTime = OffsetDateTime.now(ZoneOffset.UTC);
135 DateAndTime datetime = new DateAndTime(dtf.format(offsetDateTime));
136 Map<TargetObjectNameKey, TargetObjectName> targetObjectNames = new HashMap<>();
137 if (connService.getName() != null) {
138 for (Map.Entry<NameKey, Name> entry : connService.getName().entrySet()) {
139 targetObjectNames.put(new TargetObjectNameKey(entry.getKey().getValueName()),
140 new TargetObjectNameBuilder()
141 .setValueName(entry.getValue().getValueName())
142 .setValue(entry.getValue().getValue())
147 return new PublishTapiNotificationServiceBuilder()
148 .setUuid(new Uuid(UUID.randomUUID().toString()))
149 .setTopic(connService.getUuid().getValue())
150 .setTargetObjectIdentifier(connService.getUuid())
151 .setNotificationType(NotificationType.ATTRIBUTEVALUECHANGE)
152 .setChangedAttributes(changedStates)
153 .setEventTimeStamp(datetime)
154 .setTargetObjectName(targetObjectNames)
155 .setTargetObjectType(ObjectType.CONNECTIVITYSERVICE)
156 .setLayerProtocolName(connService.getServiceLayer())
160 private void sendNbiNotification(PublishTapiNotificationService service) {
162 this.notificationPublishService.putNotification(service);
163 } catch (InterruptedException e) {
164 LOG.warn("Cannot send notification to nbi", e);
165 Thread.currentThread().interrupt();
169 private void updateConnectivityServices() {
171 this.connectivityServiceChanges.clear();
172 InstanceIdentifier<ConnectivityContext> connectivityContextIID =
173 InstanceIdentifier.builder(Context.class).augmentation(
174 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.Context1.class)
175 .child(ConnectivityContext.class)
177 Optional<ConnectivityContext> optConnContext =
178 this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connectivityContextIID).get();
179 if (optConnContext.isEmpty()) {
180 LOG.error("Could not update TAPI connectivity services");
183 ConnectivityContext connContext = optConnContext.get();
184 Map<Uuid, EnumTypeObject[]> states = new HashMap<>();
185 if (connContext.getConnectivityService() == null) {
188 for (ConnectivityService connService : connContext.getConnectivityService().values()) {
189 LOG.info("Connectivity service = {}", connService);
190 // TODO: maybe we need to check lower connections if my new code doesnt work
191 states.put(connService.getUuid(), getStates(connService));
192 AdministrativeState adminState = (AdministrativeState) states.get(connService.getUuid())[0];
193 OperationalState operState = (OperationalState) states.get(connService.getUuid())[1];
195 InstanceIdentifier<ConnectivityService> connServIID = InstanceIdentifier
196 .builder(Context.class).augmentation(org.opendaylight.yang.gen.v1
197 .urn.onf.otcc.yang.tapi.connectivity.rev181210.Context1.class)
198 .child(ConnectivityContext.class)
199 .child(ConnectivityService.class, new ConnectivityServiceKey(connService.getUuid()))
201 ConnectivityService changedConnServ = new ConnectivityServiceBuilder()
202 .setUuid(connService.getUuid())
203 .setAdministrativeState(adminState)
204 .setOperationalState(operState)
206 this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, connServIID,
208 this.networkTransactionService.commit().get();
210 if (connService.getAdministrativeState() != adminState
211 || connService.getOperationalState() != operState) {
212 this.connectivityServiceChanges.add(changedConnServ);
215 // TODO: this last function may need some refactoring... if the PHOT_MEDIA goes down,
216 // then ODU goes down and then DSR should also go down
217 for (ConnectivityService connService : connContext.getConnectivityService().values()) {
218 AdministrativeState adminState = (AdministrativeState) states.get(connService.getUuid())[0];
219 OperationalState operState = (OperationalState) states.get(connService.getUuid())[1];
220 this.connectivityServiceChanges.addAll(updateSupportedConnectivityServices(
221 connContext.getConnectivityService().values(), connService.getUuid(), adminState, operState,
222 LayerProtocolName.ODU));
224 } catch (InterruptedException | ExecutionException e) {
225 LOG.error("Could not update TAPI connectivity services");
229 private EnumTypeObject[] getStates(ConnectivityService connService)
230 throws InterruptedException, ExecutionException {
231 OperationalState operState = OperationalState.ENABLED;
232 AdministrativeState adminState = AdministrativeState.UNLOCKED;
233 if (connService.getConnection() == null) {
234 LOG.info("No connections on service = {}", connService);
235 return new EnumTypeObject[]{null, null};
237 for (org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210
238 .connectivity.service.Connection connection : connService.getConnection().values()) {
239 InstanceIdentifier<Connection> connIID =
240 InstanceIdentifier.builder(Context.class).augmentation(org.opendaylight.yang.gen.v1.urn
241 .onf.otcc.yang.tapi.connectivity.rev181210.Context1.class)
242 .child(ConnectivityContext.class)
243 .child(Connection.class, new ConnectionKey(connection.getConnectionUuid()))
245 Optional<Connection> optConn = this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL,
247 if (optConn.isEmpty()) {
248 LOG.error("Could not get state for a TAPI connection");
251 LOG.info("State of connection {} of connectivity service {} = {}", optConn.get().getUuid().getValue(),
252 connService.getUuid().getValue(), optConn.get().getOperationalState().getName());
253 if (optConn.get().getOperationalState() == OperationalState.DISABLED) {
254 adminState = AdministrativeState.LOCKED;
255 operState = OperationalState.DISABLED;
258 return new EnumTypeObject[]{adminState, operState};
261 private void updateConnections(List<Uuid> changedOneps, List<String> onepStates) {
262 LOG.info("Updating TAPI connections");
263 LOG.info("Change in oneps = {}, new states = {}", changedOneps, onepStates);
265 //should it return a list of connections?
266 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn
267 .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext> connectivityContextIID =
268 InstanceIdentifier.builder(Context.class).augmentation(
269 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.Context1.class)
270 .child(org.opendaylight.yang.gen.v1.urn
271 .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
273 Optional<org.opendaylight.yang.gen.v1.urn
274 .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext> optConnContext =
275 this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connectivityContextIID).get();
276 if (optConnContext.isEmpty()) {
277 LOG.error(TapiStringConstants.TAPI_CONNECTION_UPDATE_ERROR);
280 if (optConnContext.get().getConnectivityService() == null) {
281 LOG.info("No TAPI connectivity service to update");
284 // TODO: order services from lower layer to upper layer
285 Map<ConnectivityServiceKey, ConnectivityService> connServMap
286 = optConnContext.get().getConnectivityService();
287 if (connServMap == null) {
288 LOG.info("No connections to update");
291 connServMap = orderConnServiceMap(connServMap);
292 for (ConnectivityService connService : connServMap.values()) {
293 LOG.info("Looping through connectivity service = {}", connService.getUuid().getValue());
294 if (connService.getConnection() == null) {
297 for (org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210
298 .connectivity.service.Connection connection : connService.getConnection().values()) {
299 InstanceIdentifier<Connection> connIID =
300 InstanceIdentifier.builder(Context.class).augmentation(org.opendaylight.yang.gen.v1.urn
301 .onf.otcc.yang.tapi.connectivity.rev181210.Context1.class)
302 .child(org.opendaylight.yang.gen.v1.urn
303 .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
304 .child(Connection.class, new ConnectionKey(connection.getConnectionUuid()))
306 Optional<Connection> optConn =
307 this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connIID).get();
308 if (optConn.isEmpty()) {
309 LOG.error(TapiStringConstants.TAPI_CONNECTION_READ_ERROR);
312 Connection newConn = optConn.get();
313 // Check LowerConnection states and if any of the lower connection is disabled then we can put
314 // the connection out of service. And based on the connection previous state we decide
315 // the update necessary
316 OperationalState newConnState = newConn.getOperationalState();
317 if (newConn.getLowerConnection() != null) {
318 newConnState = updateLowerConnections(changedOneps, onepStates,
319 newConn.getLowerConnection().values(), newConn.getOperationalState());
321 if (newConnState.equals(newConn.getOperationalState())) {
322 // To check if the oneps are from the original Top connection
323 newConnState = getConnectionState(changedOneps, onepStates, newConn);
326 LOG.info("Previous connection state = {} & New connection state = {}",
327 newConn.getOperationalState().getName(), newConnState.getName());
328 Connection changedConn = new ConnectionBuilder(newConn).setOperationalState(newConnState).build();
329 // TODO: the changed NEP is a DEG port which is not in any connection,
330 // therefore we also need to change the cross connections,
331 // the lower connections uuid and check the states.
332 // If any of the lower connections of a connection is DISABLED then the top connection is DISABLED
333 this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, connIID, changedConn);
334 this.networkTransactionService.commit().get();
337 } catch (InterruptedException | ExecutionException e) {
338 LOG.error(TapiStringConstants.TAPI_CONNECTION_UPDATE_ERROR);
342 private Map<ConnectivityServiceKey, ConnectivityService> orderConnServiceMap(
343 Map<ConnectivityServiceKey, ConnectivityService> connServMap) {
344 Map<ConnectivityServiceKey, ConnectivityService> orderedServiceMap = new HashMap<>();
345 for (LayerProtocolName lpn:this.orderedServiceLayerList) {
346 for (ConnectivityService connServ:connServMap.values()) {
347 if (connServ.getServiceLayer().equals(lpn)) {
348 LOG.info("Layer of service is equal to entry of lpn = {}", lpn);
349 orderedServiceMap.put(connServ.key(), connServ);
353 LOG.info("Ordered map of services = {}", orderedServiceMap);
354 return orderedServiceMap;
357 private OperationalState updateLowerConnections(List<Uuid> changedOneps, List<String> onepStates,
358 Collection<LowerConnection> lowerConnections,
359 OperationalState uppConnState) {
360 LOG.info("Updating lower connections");
361 OperationalState topConnectionState = uppConnState;
362 Boolean allLowerConnEna = true;
364 for (LowerConnection lowerConn:lowerConnections) {
365 InstanceIdentifier<Connection> connIID =
366 InstanceIdentifier.builder(Context.class).augmentation(org.opendaylight.yang.gen.v1.urn
367 .onf.otcc.yang.tapi.connectivity.rev181210.Context1.class)
368 .child(org.opendaylight.yang.gen.v1.urn
369 .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
370 .child(Connection.class, new ConnectionKey(lowerConn.getConnectionUuid()))
372 Optional<Connection> optConn =
373 this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connIID).get();
374 if (optConn.isEmpty()) {
375 LOG.error(TapiStringConstants.TAPI_CONNECTION_READ_ERROR);
378 Connection newConn = optConn.get(); // Current state of connection
379 if (newConn.getLowerConnection() != null) {
380 // TODO: we can receive disable here because the lower connection haven been yet looped through and
381 // therefore it is disabled but it has to be changed to enable before returning disable.
382 // We need to recall the update Lower Connections with the lower connection we are checking now
383 // and all its lower connections, until no lower connections are found in the connection
384 updateLowerConnections(changedOneps, onepStates, newConn.getLowerConnection().values(),
385 newConn.getOperationalState());
387 OperationalState newConnState = getConnectionState(changedOneps, onepStates, newConn);
388 // updated connection state if it contains a nep that has changed
389 if (!newConn.getOperationalState().equals(newConnState)) {
390 Connection changedConn = new ConnectionBuilder(newConn).setOperationalState(newConnState).build();
391 this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, connIID, changedConn);
392 this.networkTransactionService.commit().get();
394 if (newConnState.equals(OperationalState.DISABLED)) {
395 LOG.info("LowerConnection state is disable");
396 allLowerConnEna = false;
397 topConnectionState = OperationalState.DISABLED;
400 if (allLowerConnEna) {
401 return OperationalState.ENABLED;
403 return OperationalState.DISABLED;
404 } catch (InterruptedException | ExecutionException e) {
405 LOG.error(TapiStringConstants.TAPI_CONNECTION_UPDATE_ERROR);
406 return topConnectionState;
410 private OperationalState getConnectionState(List<Uuid> changedOneps, List<String> operState, Connection conn)
411 throws InterruptedException, ExecutionException {
412 LOG.info("Getting TAPI connectionState");
413 List<Uuid> connectionNeps = Objects.requireNonNull(conn.getConnectionEndPoint()).values().stream()
414 .map(NodeEdgePointRef::getNodeEdgePointUuid).collect(Collectors.toList());
415 LOG.info("Changed neps = {}", changedOneps);
416 LOG.info("Connection NEPs = {}", connectionNeps);
417 if (!Collections.disjoint(changedOneps, connectionNeps)) {
418 LOG.info("Connection neps {} are included in changed oneps {}", connectionNeps, changedOneps);
419 if ((changedOneps.contains(connectionNeps.get(0)) ? transformOperState(operState.get(
420 changedOneps.indexOf(connectionNeps.get(0)))) : null) == OperationalState.DISABLED
421 || (changedOneps.contains(connectionNeps.get(1)) ? transformOperState(operState.get(
422 changedOneps.indexOf(connectionNeps.get(1)))) : null) == OperationalState.DISABLED) {
423 return OperationalState.DISABLED;
425 LOG.info("Didnt transform correctly the states");
426 for (Uuid connectionNep : connectionNeps) {
427 Optional<org.opendaylight.yang.gen.v1.urn
428 .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint> ocep
429 = conn.getConnectionEndPoint().values().stream()
430 .filter(connectionEndPoint -> connectionEndPoint.getNodeEdgePointUuid() == connectionNep)
432 if (ocep.isEmpty()) {
435 InstanceIdentifier<OwnedNodeEdgePoint> onepIID = InstanceIdentifier.builder(Context.class)
436 .augmentation(Context1.class).child(TopologyContext.class)
437 .child(Topology.class, new TopologyKey(tapiTopoUuid))
438 .child(Node.class, new NodeKey(ocep.get().getNodeUuid()))
439 .child(OwnedNodeEdgePoint.class, new OwnedNodeEdgePointKey(connectionNep))
441 Optional<OwnedNodeEdgePoint> onep =
442 this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, onepIID).get();
443 if (onep.isEmpty() || onep.get().augmentation(OwnedNodeEdgePoint1.class) == null
444 || onep.get().augmentation(OwnedNodeEdgePoint1.class).getCepList() == null) {
447 if (onep.get().getOperationalState() == OperationalState.DISABLED
448 && !changedOneps.contains(onep.get().getUuid())) {
449 return OperationalState.DISABLED;
452 return OperationalState.ENABLED;
454 LOG.info("Connection state = {}. Going to check lower connections", conn.getOperationalState());
455 // TODO --> check all lower connections state and if all of them are enabled we return enable, otherwise disable
456 if (conn.getLowerConnection() != null && allLowerConEnabled(conn.getLowerConnection().values())) {
457 return OperationalState.ENABLED;
459 return conn.getOperationalState();
462 private boolean allLowerConEnabled(Collection<LowerConnection> lowerConnections) {
464 for (LowerConnection lowerConn:lowerConnections) {
465 InstanceIdentifier<Connection> connIID =
466 InstanceIdentifier.builder(Context.class).augmentation(org.opendaylight.yang.gen.v1.urn
467 .onf.otcc.yang.tapi.connectivity.rev181210.Context1.class)
468 .child(org.opendaylight.yang.gen.v1.urn
469 .onf.otcc.yang.tapi.connectivity.rev181210.context
470 .ConnectivityContext.class)
471 .child(Connection.class, new ConnectionKey(lowerConn.getConnectionUuid()))
473 Optional<Connection> optConn =
474 this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connIID).get();
475 if (optConn.isEmpty()) {
476 LOG.error(TapiStringConstants.TAPI_CONNECTION_READ_ERROR);
479 Connection newConn = optConn.get(); // Current state of connection
480 // updated connection state if it contains a nep that has changed
481 if (newConn.getOperationalState().equals(OperationalState.DISABLED)) {
482 LOG.info("LowerConnection state is disable");
487 } catch (InterruptedException | ExecutionException e) {
488 LOG.error(TapiStringConstants.TAPI_CONNECTION_UPDATE_ERROR);
493 private List<ConnectivityService> updateSupportedConnectivityServices(Collection<ConnectivityService> connServices,
494 Uuid supportingConnService,
495 AdministrativeState adminState,
496 OperationalState operState,
497 LayerProtocolName layer) {
498 // TODO we need to check this function
499 List<ConnectivityService> changedServices = new ArrayList<>();
500 if (adminState != AdministrativeState.LOCKED && operState != OperationalState.DISABLED) {
501 return changedServices;
504 for (ConnectivityService supportedConnService : connServices) {
505 // TODO currently supporting service uuid is saved in service layer, replace with name as soon
506 // as name is implemented
507 if (supportedConnService.getServiceLayer() != layer) {
510 InstanceIdentifier<ConnectivityService> supportedConnServIID = InstanceIdentifier
511 .builder(Context.class).augmentation(org.opendaylight.yang.gen.v1
512 .urn.onf.otcc.yang.tapi.connectivity.rev181210.Context1.class)
513 .child(org.opendaylight.yang.gen.v1
514 .urn.onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
515 .child(ConnectivityService.class, new ConnectivityServiceKey(supportedConnService.getUuid()))
517 Optional<ConnectivityService> optNewConnService = this.networkTransactionService.read(
518 LogicalDatastoreType.OPERATIONAL, supportedConnServIID).get();
519 if (optNewConnService.isEmpty()) {
520 LOG.error("Could not update TAPI connectivity service");
523 ConnectivityService newConnService = optNewConnService.get();
524 if (supportedConnService.getServiceLevel() != null
525 && supportedConnService.getServiceLevel().equals(supportingConnService.getValue())
526 && newConnService.getAdministrativeState() != AdministrativeState.LOCKED
527 && newConnService.getOperationalState() != OperationalState.DISABLED) {
529 ConnectivityService changedSupportedConnServ = new ConnectivityServiceBuilder()
530 .setUuid(supportedConnService.getUuid())
531 .setAdministrativeState(adminState)
532 .setOperationalState(operState)
534 // TODO: may need to update connections...
535 this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, supportedConnServIID,
536 changedSupportedConnServ);
537 this.networkTransactionService.commit().get();
538 changedServices.add(changedSupportedConnServ);
539 if (layer == LayerProtocolName.ODU) {
540 changedServices.addAll(updateSupportedConnectivityServices(connServices,
541 supportedConnService.getUuid(), adminState, operState, LayerProtocolName.DSR));
545 } catch (InterruptedException | ExecutionException e) {
546 LOG.error("Could not update TAPI connectivity service");
548 return changedServices;
551 private OperationalState transformOperState(String operString) {
552 LOG.debug("Operstring to be converted = {}", operString);
553 State operState = org.opendaylight.transportpce.networkmodel.util.TopologyUtils.setNetworkOperState(operString);
554 LOG.debug("State received from topologyutils = {}", operState);
555 return operState.equals(State.InService) ? OperationalState.ENABLED : OperationalState.DISABLED;