Move NetconfMessage into netconf.api.messages
[netconf.git] / plugins / netconf-client-mdsal / src / main / java / org / opendaylight / netconf / client / mdsal / NetconfDevice.java
index 074f23639d4e5d4010fd7dad3b3b009747efbe34..cf430e51fbb04877a948d09923f45f696fadeb4c 100644 (file)
@@ -37,7 +37,7 @@ import org.checkerframework.checker.lock.qual.GuardedBy;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.mdsal.dom.api.DOMRpcResult;
 import org.opendaylight.netconf.api.CapabilityURN;
-import org.opendaylight.netconf.api.NetconfMessage;
+import org.opendaylight.netconf.api.messages.NetconfMessage;
 import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
 import org.opendaylight.netconf.client.mdsal.api.DeviceActionFactory;
 import org.opendaylight.netconf.client.mdsal.api.NetconfDeviceSchemasResolver;
@@ -104,9 +104,6 @@ public class NetconfDevice implements RemoteDevice<NetconfDeviceCommunicator> {
     @GuardedBy("this")
     private boolean connected = false;
 
-    // Message transformer is constructed once the schemas are available
-    private NetconfMessageTransformer messageTransformer;
-
     public NetconfDevice(final SchemaResourcesDTO schemaResourcesDTO, final BaseNetconfSchemas baseSchemas,
             final RemoteDeviceId id, final RemoteDeviceHandler salFacade, final Executor globalProcessingExecutor,
             final boolean reconnectOnSchemasChange) {
@@ -132,11 +129,9 @@ public class NetconfDevice implements RemoteDevice<NetconfDeviceCommunicator> {
     @Override
     public void onRemoteSessionUp(final NetconfSessionPreferences remoteSessionCapabilities,
                                   final NetconfDeviceCommunicator listener) {
-        // SchemaContext setup has to be performed in a dedicated thread since
-        // we are in a netty thread in this method
-        // Yang models are being downloaded in this method and it would cause a
-        // deadlock if we used the netty thread
-        // http://netty.io/wiki/thread-model.html
+        // SchemaContext setup has to be performed in a dedicated thread since we are in a Netty thread in this method
+        // YANG models are being downloaded in this method and it would cause a deadlock if we used the netty thread
+        // https://netty.io/wiki/thread-model.html
         setConnected(true);
         LOG.debug("{}: Session to remote device established with {}", id, remoteSessionCapabilities);
 
@@ -188,7 +183,7 @@ public class NetconfDevice implements RemoteDevice<NetconfDeviceCommunicator> {
             @Override
             public void onSuccess(final DOMRpcResult domRpcResult) {
                 notificationHandler.addNotificationFilter(notification -> {
-                    if (NetconfCapabilityChange.QNAME.equals(notification.getBody().getIdentifier().getNodeType())) {
+                    if (NetconfCapabilityChange.QNAME.equals(notification.getBody().name().getNodeType())) {
                         LOG.info("{}: Schemas change detected, reconnecting", id);
                         // Only disconnect is enough,
                         // the reconnecting nature of the connector will take care of reconnecting
@@ -214,46 +209,38 @@ public class NetconfDevice implements RemoteDevice<NetconfDeviceCommunicator> {
     private synchronized void handleSalInitializationSuccess(final RemoteDeviceCommunicator listener,
             final NetconfDeviceSchema deviceSchema, final NetconfSessionPreferences remoteSessionCapabilities,
             final Rpcs deviceRpc) {
-        //NetconfDevice.SchemaSetup can complete after NetconfDeviceCommunicator was closed. In that case do nothing,
-        //since salFacade.onDeviceDisconnected was already called.
-        if (connected) {
-            final var mount = deviceSchema.mountContext();
-            messageTransformer = new NetconfMessageTransformer(mount, true,
-                resolveBaseSchema(remoteSessionCapabilities.isNotificationsSupported()));
-
-            // salFacade.onDeviceConnected has to be called before the notification handler is initialized
-            salFacade.onDeviceConnected(deviceSchema, remoteSessionCapabilities,
-                new RemoteDeviceServices(deviceRpc, deviceActionFactory == null ? null
-                    : deviceActionFactory.createDeviceAction(messageTransformer, listener)));
-            notificationHandler.onRemoteSchemaUp(messageTransformer);
-
-            LOG.info("{}: Netconf connector initialized successfully", id);
-        } else {
+        // NetconfDevice.SchemaSetup can complete after NetconfDeviceCommunicator was closed. In that case do nothing,
+        // since salFacade.onDeviceDisconnected was already called.
+        if (!connected) {
             LOG.warn("{}: Device communicator was closed before schema setup finished.", id);
+            return;
         }
+
+        final var messageTransformer = new NetconfMessageTransformer(deviceSchema.mountContext(), true,
+            resolveBaseSchema(remoteSessionCapabilities.isNotificationsSupported()));
+
+        // Order is important here: salFacade has to see the device come up and then the notificationHandler can deliver
+        // whatever notifications have been held back
+        salFacade.onDeviceConnected(deviceSchema, remoteSessionCapabilities,
+            new RemoteDeviceServices(deviceRpc, deviceActionFactory == null ? null
+                : deviceActionFactory.createDeviceAction(messageTransformer, listener)));
+        notificationHandler.onRemoteSchemaUp(messageTransformer);
+
+        LOG.info("{}: Netconf connector initialized successfully", id);
     }
 
     private void handleSalInitializationFailure(final RemoteDeviceCommunicator listener, final Throwable cause) {
-        // FIXME: pick one of these messages
         LOG.warn("{}: Unexpected error resolving device sources", id, cause);
-        LOG.error("{}: Initialization in sal failed, disconnecting from device", id, cause);
         listener.close();
-        onRemoteSessionDown();
-        resetMessageTransformer();
-
-        // FIXME: this causes salFacade to see onDeviceDisconnected() and then onDeviceFailed(), which is quite weird
+        cleanupInitialization();
         salFacade.onDeviceFailed(cause);
     }
 
-    /**
-     * Set the transformer to null as is in initial state.
-     */
-    private void resetMessageTransformer() {
-        updateTransformer(null);
-    }
-
-    private synchronized void updateTransformer(final NetconfMessageTransformer transformer) {
-        messageTransformer = transformer;
+    private synchronized void cleanupInitialization() {
+        connected = false;
+        notificationHandler.onRemoteSchemaDown();
+        sourceRegistrations.forEach(Registration::close);
+        sourceRegistrations.clear();
     }
 
     private synchronized void setConnected(final boolean connected) {
@@ -304,19 +291,8 @@ public class NetconfDevice implements RemoteDevice<NetconfDeviceCommunicator> {
 
     @Override
     public void onRemoteSessionDown() {
-        setConnected(false);
-        notificationHandler.onRemoteSchemaDown();
-
+        cleanupInitialization();
         salFacade.onDeviceDisconnected();
-        sourceRegistrations.forEach(Registration::close);
-        sourceRegistrations.clear();
-        resetMessageTransformer();
-    }
-
-    @Override
-    public void onRemoteSessionFailed(final Throwable throwable) {
-        setConnected(false);
-        salFacade.onDeviceFailed(throwable);
     }
 
     @Override