Don't use NotificationListener (TapiProvider)
[transportpce.git] / tapi / src / main / java / org / opendaylight / transportpce / tapi / listeners / TapiRendererListenerImpl.java
diff --git a/tapi/src/main/java/org/opendaylight/transportpce/tapi/listeners/TapiRendererListenerImpl.java b/tapi/src/main/java/org/opendaylight/transportpce/tapi/listeners/TapiRendererListenerImpl.java
deleted file mode 100644 (file)
index 4b40068..0000000
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * Copyright © 2021 Nokia, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.transportpce.tapi.listeners;
-
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import java.nio.charset.StandardCharsets;
-import java.time.OffsetDateTime;
-import java.time.ZoneOffset;
-import java.time.format.DateTimeFormatter;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-import java.util.UUID;
-import java.util.concurrent.ExecutionException;
-import org.opendaylight.mdsal.binding.api.DataBroker;
-import org.opendaylight.mdsal.binding.api.NotificationPublishService;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.transportpce.common.network.NetworkTransactionImpl;
-import org.opendaylight.transportpce.common.network.NetworkTransactionService;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915.RendererRpcResultSp;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev210915.TransportpceRendererListener;
-import org.opendaylight.yang.gen.v1.nbi.notifications.rev230726.PublishTapiNotificationService;
-import org.opendaylight.yang.gen.v1.nbi.notifications.rev230726.PublishTapiNotificationServiceBuilder;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.AdministrativeState;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.Context;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.DateAndTime;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.LifecycleState;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.OperationalState;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.Uuid;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.Name;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.NameKey;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.Context1;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionBuilder;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityService;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityServiceBuilder;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityServiceKey;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.Connection;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.NotificationType;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.ObjectType;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.notification.ChangedAttributes;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.notification.ChangedAttributesBuilder;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.notification.ChangedAttributesKey;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.notification.TargetObjectName;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.notification.TargetObjectNameBuilder;
-import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.notification.TargetObjectNameKey;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TapiRendererListenerImpl implements TransportpceRendererListener {
-
-    private static final Logger LOG = LoggerFactory.getLogger(TapiRendererListenerImpl.class);
-    private final DataBroker dataBroker;
-    private Uuid serviceUuid;
-    private RendererRpcResultSp serviceRpcResultSp;
-    private final NetworkTransactionService networkTransactionService;
-    private final NotificationPublishService notificationPublishService;
-
-    public TapiRendererListenerImpl(DataBroker dataBroker, NotificationPublishService notificationPublishService) {
-        this.dataBroker = dataBroker;
-        this.networkTransactionService = new NetworkTransactionImpl(this.dataBroker);
-        this.notificationPublishService = notificationPublishService;
-    }
-
-    @Override
-    public void onRendererRpcResultSp(RendererRpcResultSp notification) {
-        if (compareServiceRpcResultSp(notification)) {
-            LOG.warn("ServiceRpcResultSp already wired !");
-            return;
-        }
-        serviceRpcResultSp = notification;
-        int notifType = serviceRpcResultSp.getNotificationType().getIntValue();
-        LOG.info("Renderer '{}' Notification received : {}", serviceRpcResultSp.getNotificationType().getName(),
-                notification);
-        /* service-implementation-request. */
-        if (notifType == 3) {
-            onServiceImplementationResult(notification);
-        }
-    }
-
-    /**
-     * Process service implementation result for serviceName.
-     * @param notification RendererRpcResultSp
-     */
-    private void onServiceImplementationResult(RendererRpcResultSp notification) {
-        switch (serviceRpcResultSp.getStatus()) {
-            case Successful:
-                if (this.serviceUuid != null) {
-                    onSuccededServiceImplementation();
-                }
-                break;
-            case Failed:
-                onFailedServiceImplementation(notification.getServiceName());
-                break;
-            case  Pending:
-                LOG.warn("Service Implementation still pending according to RpcStatusEx");
-                break;
-            default:
-                LOG.warn("Service Implementation has an unknown RpcStatusEx code");
-                break;
-        }
-    }
-
-    /**
-     * Process succeeded service implementation for service.
-     */
-    private void onSuccededServiceImplementation() {
-        LOG.info("Service implemented !");
-        // TODO: update Connections and Connectivity Service states
-        ConnectivityService connectivityService = getConnectivityService(this.serviceUuid);
-        if (connectivityService == null) {
-            LOG.error("Couldnt retrieve service from datastore");
-            return;
-        }
-        LOG.info("Connectivity service = {}", connectivityService);
-        // TODO --> this throws error because the renderer goes really fast. Is this normal??
-        ConnectivityService updtConnServ = new ConnectivityServiceBuilder(connectivityService)
-            .setAdministrativeState(AdministrativeState.UNLOCKED)
-            .setLifecycleState(LifecycleState.INSTALLED)
-            .setOperationalState(OperationalState.ENABLED)
-            .build();
-        for (Connection connection:updtConnServ.nonnullConnection().values()) {
-            updateConnectionState(connection.getConnectionUuid());
-        }
-        updateConnectivityService(updtConnServ);
-        // TODO: need to send notification to kafka in case the topic exists!!
-        sendNbiNotification(createNbiNotification(updtConnServ));
-    }
-
-    /**
-     * Process failed service implementation for serviceName.
-     * @param serviceName String
-     */
-    private void onFailedServiceImplementation(String serviceName) {
-        LOG.error("Renderer implementation failed !");
-        LOG.info("PCE cancel resource done OK !");
-        Uuid suuid = new Uuid(UUID.nameUUIDFromBytes(serviceName.getBytes(StandardCharsets.UTF_8))
-                .toString());
-        // get connections of connectivity service and remove them from tapi context and then remove
-        //  service from context. The CEPs are maintained as they could be reused by another service
-        ConnectivityService connService = getConnectivityService(suuid);
-        if (connService == null) {
-            LOG.error("Service doesnt exist in tapi context");
-            return;
-        }
-        for (Connection connection:connService.getConnection().values()) {
-            deleteConnection(connection.getConnectionUuid());
-        }
-        deleteConnectivityService(suuid);
-    }
-
-    @SuppressFBWarnings(
-            value = "ES_COMPARING_STRINGS_WITH_EQ",
-            justification = "false positives, not strings but real object references comparisons")
-    private Boolean compareServiceRpcResultSp(RendererRpcResultSp notification) {
-        if (serviceRpcResultSp == null) {
-            return false;
-        }
-        if (serviceRpcResultSp.getNotificationType() != notification.getNotificationType()) {
-            return false;
-        }
-        if (serviceRpcResultSp.getServiceName() != notification.getServiceName()) {
-            return false;
-        }
-        if (serviceRpcResultSp.getStatus() != notification.getStatus()) {
-            return false;
-        }
-        if (serviceRpcResultSp.getStatusMessage() != notification.getStatusMessage()) {
-            return false;
-        }
-        return true;
-    }
-
-    private ConnectivityService getConnectivityService(Uuid suuid) {
-        // TODO: verify this is correct. Should we identify the context IID with the context UUID??
-        try {
-            // First read connectivity service with service uuid and update info
-            InstanceIdentifier<ConnectivityService> connectivityServIID =
-                InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
-                    .child(org.opendaylight.yang.gen.v1.urn
-                        .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
-                    .child(ConnectivityService.class, new ConnectivityServiceKey(suuid))
-                    .build();
-
-            Optional<ConnectivityService> optConnServ =
-                this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connectivityServIID).get();
-            if (!optConnServ.isPresent()) {
-                LOG.error("Connectivity service not found in tapi context");
-                return null;
-            }
-            return optConnServ.orElseThrow();
-        } catch (InterruptedException | ExecutionException e) {
-            LOG.error("Failed to merge TAPI connectivity", e);
-            return null;
-        }
-    }
-
-    private void updateConnectionState(Uuid connectionUuid) {
-        // TODO: verify this is correct. Should we identify the context IID with the context UUID??
-        try {
-            // First read connection with connection uuid and update info
-            InstanceIdentifier<org.opendaylight.yang.gen.v1.urn
-                .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection> connectionIID =
-                InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
-                    .child(org.opendaylight.yang.gen.v1.urn
-                        .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
-                    .child(org.opendaylight.yang.gen.v1.urn
-                            .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection.class,
-                        new ConnectionKey(connectionUuid))
-                    .build();
-
-            Optional<org.opendaylight.yang.gen.v1.urn
-                .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection> optConn =
-                this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connectionIID).get();
-            if (!optConn.isPresent()) {
-                LOG.error("Connection not found in tapi context");
-                return;
-            }
-            org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection
-                newConnection = new ConnectionBuilder(optConn.orElseThrow()).setLifecycleState(LifecycleState.INSTALLED)
-                    .setOperationalState(OperationalState.ENABLED).build();
-            // merge in datastore
-            this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, connectionIID,
-                    newConnection);
-            this.networkTransactionService.commit().get();
-            LOG.info("TAPI connection merged successfully.");
-        } catch (InterruptedException | ExecutionException e) {
-            LOG.error("Failed to merge TAPI connection", e);
-        }
-    }
-
-    private void updateConnectivityService(ConnectivityService updtConnServ) {
-        // TODO: verify this is correct. Should we identify the context IID with the context UUID??
-        try {
-            // First read connectivity service with connectivity service uuid and update info
-            InstanceIdentifier<ConnectivityService> connServIID =
-                InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
-                    .child(org.opendaylight.yang.gen.v1.urn
-                        .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
-                    .child(ConnectivityService.class, new ConnectivityServiceKey(updtConnServ.getUuid()))
-                    .build();
-
-            Optional<ConnectivityService> optConnServ =
-                this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connServIID).get();
-            if (!optConnServ.isPresent()) {
-                LOG.error("Connection not found in tapi context");
-                return;
-            }
-            ConnectivityService newConnServ = new ConnectivityServiceBuilder(updtConnServ).build();
-            // merge in datastore
-            this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, connServIID,
-                    newConnServ);
-            this.networkTransactionService.commit().get();
-            LOG.info("TAPI connectivity service merged successfully.");
-        } catch (InterruptedException | ExecutionException e) {
-            LOG.error("Failed to merge TAPI connectivity service", e);
-        }
-    }
-
-    private void deleteConnectivityService(Uuid suuid) {
-        // First read connectivity service with service uuid and update info
-        InstanceIdentifier<ConnectivityService> connectivityServIID =
-            InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
-                .child(org.opendaylight.yang.gen.v1.urn
-                    .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
-                .child(ConnectivityService.class, new ConnectivityServiceKey(suuid))
-                .build();
-        try {
-            this.networkTransactionService.delete(LogicalDatastoreType.OPERATIONAL, connectivityServIID);
-            this.networkTransactionService.commit().get();
-        } catch (InterruptedException | ExecutionException e) {
-            LOG.error("Failed to delete TAPI connectivity service", e);
-        }
-    }
-
-    private void deleteConnection(Uuid connectionUuid) {
-        // First read connectivity service with service uuid and update info
-        InstanceIdentifier<org.opendaylight.yang.gen.v1
-            .urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection> connectionIID =
-            InstanceIdentifier.builder(Context.class).augmentation(Context1.class)
-                .child(org.opendaylight.yang.gen.v1.urn
-                    .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class)
-                .child(org.opendaylight.yang.gen.v1.urn
-                        .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection.class,
-                    new org.opendaylight.yang.gen.v1.urn
-                        .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey(
-                            connectionUuid))
-                .build();
-        try {
-            this.networkTransactionService.delete(LogicalDatastoreType.OPERATIONAL, connectionIID);
-            this.networkTransactionService.commit().get();
-        } catch (InterruptedException | ExecutionException e) {
-            LOG.error("Failed to delete TAPI connection", e);
-        }
-    }
-
-    private void sendNbiNotification(PublishTapiNotificationService service) {
-        try {
-            this.notificationPublishService.putNotification(service);
-        } catch (InterruptedException e) {
-            LOG.warn("Cannot send notification to nbi", e);
-            Thread.currentThread().interrupt();
-        }
-    }
-
-    private PublishTapiNotificationService createNbiNotification(ConnectivityService connService) {
-        if (connService == null) {
-            LOG.error("ConnService is null");
-            return null;
-        }
-        /*
-        Map<ChangedAttributesKey, ChangedAttributes> changedStates = changedAttributesMap.entrySet()
-                .stream()
-                .filter(e -> e.getKey().getValueName().equals("administrative")
-                        || e.getKey().getValueName().equals("operational"))
-                .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));
-
-         */
-        Map<ChangedAttributesKey, ChangedAttributes> changedStates = new HashMap<>();
-        changedStates.put(new ChangedAttributesKey("administrativeState"),
-            new ChangedAttributesBuilder()
-                .setNewValue(connService.getAdministrativeState().getName())
-                .setOldValue(AdministrativeState.LOCKED.getName())
-                .setValueName("administrativeState").build());
-        changedStates.put(new ChangedAttributesKey("operationalState"),
-            new ChangedAttributesBuilder()
-                .setNewValue(connService.getOperationalState().getName())
-                .setOldValue(OperationalState.DISABLED.getName())
-                .setValueName("operationalState").build());
-        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssxxx");
-        OffsetDateTime offsetDateTime = OffsetDateTime.now(ZoneOffset.UTC);
-        DateAndTime datetime = new DateAndTime(dtf.format(offsetDateTime));
-        Map<TargetObjectNameKey, TargetObjectName> targetObjectNames = new HashMap<>();
-        if (connService.getName() != null) {
-            for (Map.Entry<NameKey, Name> entry : connService.getName().entrySet()) {
-                targetObjectNames.put(new TargetObjectNameKey(entry.getKey().getValueName()),
-                    new TargetObjectNameBuilder()
-                        .setValueName(entry.getValue().getValueName())
-                        .setValue(entry.getValue().getValue())
-                        .build());
-            }
-        }
-
-        return new PublishTapiNotificationServiceBuilder()
-            .setUuid(new Uuid(UUID.randomUUID().toString()))
-            .setTopic(connService.getUuid().getValue())
-            .setTargetObjectIdentifier(connService.getUuid())
-            .setNotificationType(NotificationType.ATTRIBUTEVALUECHANGE)
-            .setChangedAttributes(changedStates)
-            .setEventTimeStamp(datetime)
-            .setTargetObjectName(targetObjectNames)
-            .setTargetObjectType(ObjectType.CONNECTIVITYSERVICE)
-            .setLayerProtocolName(connService.getServiceLayer())
-            .build();
-    }
-
-    public void setServiceUuid(Uuid serviceUuid) {
-        this.serviceUuid = serviceUuid;
-    }
-}