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;
23 import java.util.UUID;
24 import java.util.concurrent.ExecutionException;
25 import java.util.stream.Collectors;
26 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
27 import org.opendaylight.mdsal.binding.api.NotificationService.CompositeListener;
28 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
29 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
30 import org.opendaylight.transportpce.tapi.TapiStringConstants;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State;
32 import org.opendaylight.yang.gen.v1.nbi.notifications.rev230726.PublishTapiNotificationService;
33 import org.opendaylight.yang.gen.v1.nbi.notifications.rev230726.PublishTapiNotificationServiceBuilder;
34 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.AdministrativeState;
35 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.Context;
36 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.DateAndTime;
37 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.LayerProtocolName;
38 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.OperationalState;
39 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.Uuid;
40 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.Name;
41 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.NameKey;
42 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.OwnedNodeEdgePoint1;
43 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connection.LowerConnection;
44 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection;
45 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionBuilder;
46 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey;
47 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityService;
48 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityServiceBuilder;
49 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityServiceKey;
50 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext;
51 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.NameAndValueChange;
52 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.Notification;
53 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.NotificationType;
54 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.ObjectType;
55 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.notification.ChangedAttributes;
56 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.notification.ChangedAttributesBuilder;
57 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.notification.ChangedAttributesKey;
58 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.notification.TargetObjectName;
59 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.notification.TargetObjectNameBuilder;
60 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.notification.TargetObjectNameKey;
61 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.Context1;
62 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.NodeEdgePointRef;
63 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.context.TopologyContext;
64 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePoint;
65 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePointKey;
66 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node;
67 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.NodeKey;
68 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.Topology;
69 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.TopologyKey;
70 import org.opendaylight.yangtools.yang.binding.EnumTypeObject;
71 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
72 import org.osgi.service.component.annotations.Activate;
73 import org.osgi.service.component.annotations.Component;
74 import org.osgi.service.component.annotations.Reference;
75 import org.slf4j.Logger;
76 import org.slf4j.LoggerFactory;
78 @Component(service = TapiNetworkModelNotificationHandler.class)
79 public class TapiNetworkModelNotificationHandler {
81 private static final Logger LOG = LoggerFactory.getLogger(TapiNetworkModelNotificationHandler.class);
82 private final NetworkTransactionService networkTransactionService;
83 private final NotificationPublishService notificationPublishService;
84 private final List<ConnectivityService> connectivityServiceChanges = new ArrayList<>();
85 private final Uuid tapiTopoUuid = new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER
86 .getBytes(StandardCharsets.UTF_8)).toString());
87 private final List<LayerProtocolName> orderedServiceLayerList;
90 public TapiNetworkModelNotificationHandler(@Reference NetworkTransactionService networkTransactionService,
91 @Reference NotificationPublishService notificationPublishService) {
92 this.networkTransactionService = networkTransactionService;
93 this.notificationPublishService = notificationPublishService;
94 this.orderedServiceLayerList = List.of(LayerProtocolName.PHOTONICMEDIA, LayerProtocolName.ODU,
95 LayerProtocolName.DSR, LayerProtocolName.ETH);
96 LOG.debug("TapiNetworkModelListenerImpl instantiated");
99 public CompositeListener getCompositeListener() {
100 return new CompositeListener(Set.of(
101 new CompositeListener.Component<>(Notification.class, this::onNotification)));
104 private void onNotification(Notification notification) {
105 LOG.info("Received network model notification {}", notification);
106 if (notification.getNotificationType() == NotificationType.ATTRIBUTEVALUECHANGE
107 && notification.getTargetObjectType() == ObjectType.NODEEDGEPOINT) {
108 if (notification.getChangedAttributes() == null) {
111 // TODO: need to re-think this to update first the connections from roadm to roadm and then the others
112 updateConnections(notification.getChangedAttributes().keySet().stream()
113 .map(changedAttributesKey -> new Uuid(changedAttributesKey.getValueName()))
114 .collect(Collectors.toList()),
115 notification.getChangedAttributes().values().stream()
116 .map(NameAndValueChange::getNewValue)
117 .collect(Collectors.toList()));
118 updateConnectivityServices();
119 // todo set attributes
120 for (ConnectivityService connService : this.connectivityServiceChanges) {
121 sendNbiNotification(createNbiNotification(connService));
126 private PublishTapiNotificationService createNbiNotification(ConnectivityService connService) {
127 if (connService == null) {
128 LOG.error("ConnService is null");
131 Map<ChangedAttributesKey, ChangedAttributes> changedStates = new HashMap<>();
132 changedStates.put(new ChangedAttributesKey("administrativeState"),
133 new ChangedAttributesBuilder()
134 .setNewValue(connService.getAdministrativeState().getName())
135 .setOldValue(connService.getAdministrativeState().equals(AdministrativeState.UNLOCKED)
136 ? AdministrativeState.LOCKED.getName() : AdministrativeState.UNLOCKED.getName())
137 .setValueName("administrativeState").build());
138 changedStates.put(new ChangedAttributesKey("operationalState"),
139 new ChangedAttributesBuilder()
140 .setNewValue(connService.getOperationalState().getName())
141 .setOldValue(connService.getOperationalState().equals(OperationalState.ENABLED)
142 ? OperationalState.DISABLED.getName() : OperationalState.ENABLED.getName())
143 .setValueName("operationalState").build());
144 DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssxxx");
145 OffsetDateTime offsetDateTime = OffsetDateTime.now(ZoneOffset.UTC);
146 DateAndTime datetime = new DateAndTime(dtf.format(offsetDateTime));
147 Map<TargetObjectNameKey, TargetObjectName> targetObjectNames = new HashMap<>();
148 if (connService.getName() != null) {
149 for (Map.Entry<NameKey, Name> entry : connService.getName().entrySet()) {
150 targetObjectNames.put(new TargetObjectNameKey(entry.getKey().getValueName()),
151 new TargetObjectNameBuilder()
152 .setValueName(entry.getValue().getValueName())
153 .setValue(entry.getValue().getValue())
158 return new PublishTapiNotificationServiceBuilder()
159 .setUuid(new Uuid(UUID.randomUUID().toString()))
160 .setTopic(connService.getUuid().getValue())
161 .setTargetObjectIdentifier(connService.getUuid())
162 .setNotificationType(NotificationType.ATTRIBUTEVALUECHANGE)
163 .setChangedAttributes(changedStates)
164 .setEventTimeStamp(datetime)
165 .setTargetObjectName(targetObjectNames)
166 .setTargetObjectType(ObjectType.CONNECTIVITYSERVICE)
167 .setLayerProtocolName(connService.getServiceLayer())
171 private void sendNbiNotification(PublishTapiNotificationService service) {
173 this.notificationPublishService.putNotification(service);
174 } catch (InterruptedException e) {
175 LOG.warn("Cannot send notification to nbi", e);
176 Thread.currentThread().interrupt();
180 private void updateConnectivityServices() {
182 this.connectivityServiceChanges.clear();
183 InstanceIdentifier<ConnectivityContext> connectivityContextIID =
184 InstanceIdentifier.builder(Context.class).augmentation(
185 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.Context1.class)
186 .child(ConnectivityContext.class)
188 Optional<ConnectivityContext> optConnContext =
189 this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connectivityContextIID).get();
190 if (optConnContext.isEmpty()) {
191 LOG.error("Could not update TAPI connectivity services");
194 ConnectivityContext connContext = optConnContext.orElseThrow();
195 Map<Uuid, EnumTypeObject[]> states = new HashMap<>();
196 if (connContext.getConnectivityService() == null) {
199 for (ConnectivityService connService : connContext.getConnectivityService().values()) {
200 LOG.info("Connectivity service = {}", connService);
201 // TODO: maybe we need to check lower connections if my new code doesnt work
202 states.put(connService.getUuid(), getStates(connService));
203 AdministrativeState adminState = (AdministrativeState) states.get(connService.getUuid())[0];
204 OperationalState operState = (OperationalState) states.get(connService.getUuid())[1];
206 InstanceIdentifier<ConnectivityService> connServIID = InstanceIdentifier
207 .builder(Context.class).augmentation(org.opendaylight.yang.gen.v1
208 .urn.onf.otcc.yang.tapi.connectivity.rev181210.Context1.class)
209 .child(ConnectivityContext.class)
210 .child(ConnectivityService.class, new ConnectivityServiceKey(connService.getUuid()))
212 ConnectivityService changedConnServ = new ConnectivityServiceBuilder()
213 .setUuid(connService.getUuid())
214 .setAdministrativeState(adminState)
215 .setOperationalState(operState)
217 this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, connServIID,
219 this.networkTransactionService.commit().get();
221 if (connService.getAdministrativeState() != adminState
222 || connService.getOperationalState() != operState) {
223 this.connectivityServiceChanges.add(changedConnServ);
226 // TODO: this last function may need some refactoring... if the PHOT_MEDIA goes down,
227 // then ODU goes down and then DSR should also go down
228 for (ConnectivityService connService : connContext.getConnectivityService().values()) {
229 AdministrativeState adminState = (AdministrativeState) states.get(connService.getUuid())[0];
230 OperationalState operState = (OperationalState) states.get(connService.getUuid())[1];
231 this.connectivityServiceChanges.addAll(updateSupportedConnectivityServices(
232 connContext.getConnectivityService().values(), connService.getUuid(), adminState, operState,
233 LayerProtocolName.ODU));
235 } catch (InterruptedException | ExecutionException e) {
236 LOG.error("Could not update TAPI connectivity services");
240 private EnumTypeObject[] getStates(ConnectivityService connService)
241 throws InterruptedException, ExecutionException {
242 OperationalState operState = OperationalState.ENABLED;
243 AdministrativeState adminState = AdministrativeState.UNLOCKED;
244 if (connService.getConnection() == null) {
245 LOG.info("No connections on service = {}", connService);
246 return new EnumTypeObject[]{null, null};
248 for (org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210
249 .connectivity.service.Connection connection : connService.getConnection().values()) {
250 InstanceIdentifier<Connection> connIID =
251 InstanceIdentifier.builder(Context.class).augmentation(org.opendaylight.yang.gen.v1.urn
252 .onf.otcc.yang.tapi.connectivity.rev181210.Context1.class)
253 .child(ConnectivityContext.class)
254 .child(Connection.class, new ConnectionKey(connection.getConnectionUuid()))
256 Optional<Connection> optConn = this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL,
258 if (optConn.isEmpty()) {
259 LOG.error("Could not get state for a TAPI connection");
262 LOG.info("State of connection {} of connectivity service {} = {}", optConn.orElseThrow().getUuid()
263 .getValue(), connService.getUuid().getValue(), optConn.orElseThrow().getOperationalState().getName());
264 if (optConn.orElseThrow().getOperationalState() == OperationalState.DISABLED) {
265 adminState = AdministrativeState.LOCKED;
266 operState = OperationalState.DISABLED;
269 return new EnumTypeObject[]{adminState, operState};
272 private void updateConnections(List<Uuid> changedOneps, List<String> onepStates) {
273 LOG.info("Updating TAPI connections");
274 LOG.info("Change in oneps = {}, new states = {}", changedOneps, onepStates);
276 //should it return a list of connections?
277 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn
278 .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext> connectivityContextIID =
279 InstanceIdentifier.builder(Context.class).augmentation(
280 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.Context1.class)
281 .child(org.opendaylight.yang.gen.v1.urn
282 .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
284 Optional<org.opendaylight.yang.gen.v1.urn
285 .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext> optConnContext =
286 this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connectivityContextIID).get();
287 if (optConnContext.isEmpty()) {
288 LOG.error(TapiStringConstants.TAPI_CONNECTION_UPDATE_ERROR);
291 if (optConnContext.orElseThrow().getConnectivityService() == null) {
292 LOG.info("No TAPI connectivity service to update");
295 // TODO: order services from lower layer to upper layer
296 Map<ConnectivityServiceKey, ConnectivityService> connServMap
297 = optConnContext.orElseThrow().getConnectivityService();
298 if (connServMap == null) {
299 LOG.info("No connections to update");
302 connServMap = orderConnServiceMap(connServMap);
303 for (ConnectivityService connService : connServMap.values()) {
304 LOG.info("Looping through connectivity service = {}", connService.getUuid().getValue());
305 if (connService.getConnection() == null) {
308 for (org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210
309 .connectivity.service.Connection connection : connService.getConnection().values()) {
310 InstanceIdentifier<Connection> connIID =
311 InstanceIdentifier.builder(Context.class).augmentation(org.opendaylight.yang.gen.v1.urn
312 .onf.otcc.yang.tapi.connectivity.rev181210.Context1.class)
313 .child(org.opendaylight.yang.gen.v1.urn
314 .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
315 .child(Connection.class, new ConnectionKey(connection.getConnectionUuid()))
317 Optional<Connection> optConn =
318 this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connIID).get();
319 if (optConn.isEmpty()) {
320 LOG.error(TapiStringConstants.TAPI_CONNECTION_READ_ERROR);
323 Connection newConn = optConn.orElseThrow();
324 // Check LowerConnection states and if any of the lower connection is disabled then we can put
325 // the connection out of service. And based on the connection previous state we decide
326 // the update necessary
327 OperationalState newConnState = newConn.getOperationalState();
328 if (newConn.getLowerConnection() != null) {
329 newConnState = updateLowerConnections(changedOneps, onepStates,
330 newConn.getLowerConnection().values(), newConn.getOperationalState());
332 if (newConnState.equals(newConn.getOperationalState())) {
333 // To check if the oneps are from the original Top connection
334 newConnState = getConnectionState(changedOneps, onepStates, newConn);
337 LOG.info("Previous connection state = {} & New connection state = {}",
338 newConn.getOperationalState().getName(), newConnState.getName());
339 Connection changedConn = new ConnectionBuilder(newConn).setOperationalState(newConnState).build();
340 // TODO: the changed NEP is a DEG port which is not in any connection,
341 // therefore we also need to change the cross connections,
342 // the lower connections uuid and check the states.
343 // If any of the lower connections of a connection is DISABLED then the top connection is DISABLED
344 this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, connIID, changedConn);
345 this.networkTransactionService.commit().get();
348 } catch (InterruptedException | ExecutionException e) {
349 LOG.error(TapiStringConstants.TAPI_CONNECTION_UPDATE_ERROR);
353 private Map<ConnectivityServiceKey, ConnectivityService> orderConnServiceMap(
354 Map<ConnectivityServiceKey, ConnectivityService> connServMap) {
355 Map<ConnectivityServiceKey, ConnectivityService> orderedServiceMap = new HashMap<>();
356 for (LayerProtocolName lpn:this.orderedServiceLayerList) {
357 for (ConnectivityService connServ:connServMap.values()) {
358 if (connServ.getServiceLayer().equals(lpn)) {
359 LOG.info("Layer of service is equal to entry of lpn = {}", lpn);
360 orderedServiceMap.put(connServ.key(), connServ);
364 LOG.info("Ordered map of services = {}", orderedServiceMap);
365 return orderedServiceMap;
368 private OperationalState updateLowerConnections(List<Uuid> changedOneps, List<String> onepStates,
369 Collection<LowerConnection> lowerConnections,
370 OperationalState uppConnState) {
371 LOG.info("Updating lower connections");
372 OperationalState topConnectionState = uppConnState;
373 Boolean allLowerConnEna = true;
375 for (LowerConnection lowerConn:lowerConnections) {
376 InstanceIdentifier<Connection> connIID =
377 InstanceIdentifier.builder(Context.class).augmentation(org.opendaylight.yang.gen.v1.urn
378 .onf.otcc.yang.tapi.connectivity.rev181210.Context1.class)
379 .child(org.opendaylight.yang.gen.v1.urn
380 .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
381 .child(Connection.class, new ConnectionKey(lowerConn.getConnectionUuid()))
383 Optional<Connection> optConn =
384 this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connIID).get();
385 if (optConn.isEmpty()) {
386 LOG.error(TapiStringConstants.TAPI_CONNECTION_READ_ERROR);
389 Connection newConn = optConn.orElseThrow(); // Current state of connection
390 if (newConn.getLowerConnection() != null) {
391 // TODO: we can receive disable here because the lower connection haven been yet looped through and
392 // therefore it is disabled but it has to be changed to enable before returning disable.
393 // We need to recall the update Lower Connections with the lower connection we are checking now
394 // and all its lower connections, until no lower connections are found in the connection
395 updateLowerConnections(changedOneps, onepStates, newConn.getLowerConnection().values(),
396 newConn.getOperationalState());
398 OperationalState newConnState = getConnectionState(changedOneps, onepStates, newConn);
399 // updated connection state if it contains a nep that has changed
400 if (!newConn.getOperationalState().equals(newConnState)) {
401 Connection changedConn = new ConnectionBuilder(newConn).setOperationalState(newConnState).build();
402 this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, connIID, changedConn);
403 this.networkTransactionService.commit().get();
405 if (newConnState.equals(OperationalState.DISABLED)) {
406 LOG.info("LowerConnection state is disable");
407 allLowerConnEna = false;
408 topConnectionState = OperationalState.DISABLED;
411 if (allLowerConnEna) {
412 return OperationalState.ENABLED;
414 return OperationalState.DISABLED;
415 } catch (InterruptedException | ExecutionException e) {
416 LOG.error(TapiStringConstants.TAPI_CONNECTION_UPDATE_ERROR);
417 return topConnectionState;
421 private OperationalState getConnectionState(List<Uuid> changedOneps, List<String> operState, Connection conn)
422 throws InterruptedException, ExecutionException {
423 LOG.info("Getting TAPI connectionState");
424 List<Uuid> connectionNeps = Objects.requireNonNull(conn.getConnectionEndPoint()).values().stream()
425 .map(NodeEdgePointRef::getNodeEdgePointUuid).collect(Collectors.toList());
426 LOG.info("Changed neps = {}", changedOneps);
427 LOG.info("Connection NEPs = {}", connectionNeps);
428 if (!Collections.disjoint(changedOneps, connectionNeps)) {
429 LOG.info("Connection neps {} are included in changed oneps {}", connectionNeps, changedOneps);
430 if ((changedOneps.contains(connectionNeps.get(0)) ? transformOperState(operState.get(
431 changedOneps.indexOf(connectionNeps.get(0)))) : null) == OperationalState.DISABLED
432 || (changedOneps.contains(connectionNeps.get(1)) ? transformOperState(operState.get(
433 changedOneps.indexOf(connectionNeps.get(1)))) : null) == OperationalState.DISABLED) {
434 return OperationalState.DISABLED;
436 LOG.info("Didnt transform correctly the states");
437 for (Uuid connectionNep : connectionNeps) {
438 Optional<org.opendaylight.yang.gen.v1.urn
439 .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint> ocep
440 = conn.getConnectionEndPoint().values().stream()
441 .filter(connectionEndPoint -> connectionEndPoint.getNodeEdgePointUuid() == connectionNep)
443 if (ocep.isEmpty()) {
446 InstanceIdentifier<OwnedNodeEdgePoint> onepIID = InstanceIdentifier.builder(Context.class)
447 .augmentation(Context1.class).child(TopologyContext.class)
448 .child(Topology.class, new TopologyKey(tapiTopoUuid))
449 .child(Node.class, new NodeKey(ocep.orElseThrow().getNodeUuid()))
450 .child(OwnedNodeEdgePoint.class, new OwnedNodeEdgePointKey(connectionNep))
452 Optional<OwnedNodeEdgePoint> onep =
453 this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, onepIID).get();
454 if (onep.isEmpty() || onep.orElseThrow().augmentation(OwnedNodeEdgePoint1.class) == null
455 || onep.orElseThrow().augmentation(OwnedNodeEdgePoint1.class).getCepList() == null) {
458 if (onep.orElseThrow().getOperationalState() == OperationalState.DISABLED
459 && !changedOneps.contains(onep.orElseThrow().getUuid())) {
460 return OperationalState.DISABLED;
463 return OperationalState.ENABLED;
465 LOG.info("Connection state = {}. Going to check lower connections", conn.getOperationalState());
466 // TODO --> check all lower connections state and if all of them are enabled we return enable, otherwise disable
467 if (conn.getLowerConnection() != null && allLowerConEnabled(conn.getLowerConnection().values())) {
468 return OperationalState.ENABLED;
470 return conn.getOperationalState();
473 private boolean allLowerConEnabled(Collection<LowerConnection> lowerConnections) {
475 for (LowerConnection lowerConn:lowerConnections) {
476 InstanceIdentifier<Connection> connIID =
477 InstanceIdentifier.builder(Context.class).augmentation(org.opendaylight.yang.gen.v1.urn
478 .onf.otcc.yang.tapi.connectivity.rev181210.Context1.class)
479 .child(org.opendaylight.yang.gen.v1.urn
480 .onf.otcc.yang.tapi.connectivity.rev181210.context
481 .ConnectivityContext.class)
482 .child(Connection.class, new ConnectionKey(lowerConn.getConnectionUuid()))
484 Optional<Connection> optConn =
485 this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connIID).get();
486 if (optConn.isEmpty()) {
487 LOG.error(TapiStringConstants.TAPI_CONNECTION_READ_ERROR);
490 Connection newConn = optConn.orElseThrow(); // Current state of connection
491 // updated connection state if it contains a nep that has changed
492 if (newConn.getOperationalState().equals(OperationalState.DISABLED)) {
493 LOG.info("LowerConnection state is disable");
498 } catch (InterruptedException | ExecutionException e) {
499 LOG.error(TapiStringConstants.TAPI_CONNECTION_UPDATE_ERROR);
504 private List<ConnectivityService> updateSupportedConnectivityServices(Collection<ConnectivityService> connServices,
505 Uuid supportingConnService,
506 AdministrativeState adminState,
507 OperationalState operState,
508 LayerProtocolName layer) {
509 // TODO we need to check this function
510 List<ConnectivityService> changedServices = new ArrayList<>();
511 if (adminState != AdministrativeState.LOCKED && operState != OperationalState.DISABLED) {
512 return changedServices;
515 for (ConnectivityService supportedConnService : connServices) {
516 // TODO currently supporting service uuid is saved in service layer, replace with name as soon
517 // as name is implemented
518 if (supportedConnService.getServiceLayer() != layer) {
521 InstanceIdentifier<ConnectivityService> supportedConnServIID = InstanceIdentifier
522 .builder(Context.class).augmentation(org.opendaylight.yang.gen.v1
523 .urn.onf.otcc.yang.tapi.connectivity.rev181210.Context1.class)
524 .child(org.opendaylight.yang.gen.v1
525 .urn.onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
526 .child(ConnectivityService.class, new ConnectivityServiceKey(supportedConnService.getUuid()))
528 Optional<ConnectivityService> optNewConnService = this.networkTransactionService.read(
529 LogicalDatastoreType.OPERATIONAL, supportedConnServIID).get();
530 if (optNewConnService.isEmpty()) {
531 LOG.error("Could not update TAPI connectivity service");
534 ConnectivityService newConnService = optNewConnService.orElseThrow();
535 if (supportedConnService.getServiceLevel() != null
536 && supportedConnService.getServiceLevel().equals(supportingConnService.getValue())
537 && newConnService.getAdministrativeState() != AdministrativeState.LOCKED
538 && newConnService.getOperationalState() != OperationalState.DISABLED) {
540 ConnectivityService changedSupportedConnServ = new ConnectivityServiceBuilder()
541 .setUuid(supportedConnService.getUuid())
542 .setAdministrativeState(adminState)
543 .setOperationalState(operState)
545 // TODO: may need to update connections...
546 this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, supportedConnServIID,
547 changedSupportedConnServ);
548 this.networkTransactionService.commit().get();
549 changedServices.add(changedSupportedConnServ);
550 if (layer == LayerProtocolName.ODU) {
551 changedServices.addAll(updateSupportedConnectivityServices(connServices,
552 supportedConnService.getUuid(), adminState, operState, LayerProtocolName.DSR));
556 } catch (InterruptedException | ExecutionException e) {
557 LOG.error("Could not update TAPI connectivity service");
559 return changedServices;
562 private OperationalState transformOperState(String operString) {
563 LOG.debug("Operstring to be converted = {}", operString);
564 State operState = org.opendaylight.transportpce.networkmodel.util.TopologyUtils.setNetworkOperState(operString);
565 LOG.debug("State received from topologyutils = {}", operState);
566 return operState.equals(State.InService) ? OperationalState.ENABLED : OperationalState.DISABLED;