Merge "Implementation of ModuleShardStrategy"
[controller.git] / opendaylight / md-sal / sal-netconf-connector / src / main / java / org / opendaylight / controller / sal / connect / netconf / sal / NetconfDeviceSalProvider.java
index fc54bfbc3d8f0b93ec58d9df664b26815a500184..cf9174dd50d707ef36c5e80deefce3ea8f8be20c 100644 (file)
@@ -11,15 +11,21 @@ import com.google.common.base.Preconditions;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.concurrent.ExecutorService;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
 import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
 import org.opendaylight.controller.sal.core.api.Broker;
 import org.opendaylight.controller.sal.core.api.Provider;
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
+import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
 import org.opendaylight.yangtools.yang.binding.RpcService;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -29,17 +35,17 @@ final class NetconfDeviceSalProvider implements AutoCloseable, Provider, Binding
 
     private final RemoteDeviceId id;
     private final ExecutorService executor;
-    private volatile MountProvisionInstance mountInstance;
     private volatile NetconfDeviceDatastoreAdapter datastoreAdapter;
+    private MountInstance mountInstance;
 
     public NetconfDeviceSalProvider(final RemoteDeviceId deviceId, final ExecutorService executor) {
         this.id = deviceId;
         this.executor = executor;
     }
 
-    public MountProvisionInstance getMountInstance() {
+    public MountInstance getMountInstance() {
         Preconditions.checkState(mountInstance != null,
-                "%s: Sal provider was not initialized by sal. Cannot get mount instance", id);
+                "%s: Mount instance was not initialized by sal. Cannot get mount instance", id);
         return mountInstance;
     }
 
@@ -51,12 +57,12 @@ final class NetconfDeviceSalProvider implements AutoCloseable, Provider, Binding
 
     @Override
     public void onSessionInitiated(final Broker.ProviderSession session) {
-        final MountProvisionService mountService = session.getService(MountProvisionService.class);
+        logger.debug("{}: (BI)Session with sal established {}", id, session);
+
+        final DOMMountPointService mountService = session.getService(DOMMountPointService.class);
         if (mountService != null) {
-            mountInstance = mountService.createOrGetMountPoint(id.getPath());
+            mountInstance = new MountInstance(mountService, id);
         }
-
-        logger.debug("{}: (BI)Session with sal established {}", id, session);
     }
 
     @Override
@@ -76,20 +82,78 @@ final class NetconfDeviceSalProvider implements AutoCloseable, Provider, Binding
 
     @Override
     public void onSessionInitiated(final BindingAwareBroker.ProviderContext session) {
-        final DataProviderService dataBroker = session.getSALService(DataProviderService.class);
-        datastoreAdapter = new NetconfDeviceDatastoreAdapter(id, dataBroker, executor);
-
         logger.debug("{}: Session with sal established {}", id, session);
+
+        final DataBroker dataBroker = session.getSALService(DataBroker.class);
+        datastoreAdapter = new NetconfDeviceDatastoreAdapter(id, dataBroker);
     }
 
     @Override
-    public void onSessionInitialized(final BindingAwareBroker.ConsumerContext session) {
-    }
+    public void onSessionInitialized(final BindingAwareBroker.ConsumerContext session) {}
 
     public void close() throws Exception {
-        mountInstance = null;
+        mountInstance.close();
         datastoreAdapter.close();
         datastoreAdapter = null;
     }
 
+    static final class MountInstance implements AutoCloseable {
+
+        private DOMMountPointService mountService;
+        private final RemoteDeviceId id;
+        private ObjectRegistration<DOMMountPoint> registration;
+        private NotificationPublishService notificationSerivce;
+
+        MountInstance(final DOMMountPointService mountService, final RemoteDeviceId id) {
+            this.mountService = Preconditions.checkNotNull(mountService);
+            this.id = Preconditions.checkNotNull(id);
+        }
+
+        synchronized void onDeviceConnected(final SchemaContext initialCtx,
+                final DOMDataBroker broker, final RpcProvisionRegistry rpc,
+                final NotificationPublishService notificationSerivce) {
+
+            Preconditions.checkNotNull(mountService, "Closed");
+            Preconditions.checkState(registration == null, "Already initialized");
+
+            final DOMMountPointService.DOMMountPointBuilder mountBuilder = mountService.createMountPoint(id.getPath());
+            mountBuilder.addInitialSchemaContext(initialCtx);
+
+            mountBuilder.addService(DOMDataBroker.class, broker);
+            mountBuilder.addService(RpcProvisionRegistry.class, rpc);
+            this.notificationSerivce = notificationSerivce;
+            mountBuilder.addService(NotificationPublishService.class, notificationSerivce);
+
+            registration = mountBuilder.register();
+        }
+
+        synchronized void onDeviceDisconnected() {
+            if(registration == null) {
+                return;
+            }
+
+            try {
+                registration.close();
+            } catch (final Exception e) {
+                // Only log and ignore
+                logger.warn("Unable to unregister mount instance for {}. Ignoring exception", id.getPath(), e);
+            } finally {
+                registration = null;
+            }
+        }
+
+        @Override
+        synchronized public void close() throws Exception {
+            if(registration != null) {
+                onDeviceDisconnected();
+            }
+            mountService = null;
+        }
+
+        public synchronized void publish(final CompositeNode domNotification) {
+            Preconditions.checkNotNull(notificationSerivce, "Device not set up yet, cannot handle notification {}", domNotification);
+            notificationSerivce.publish(domNotification);
+        }
+    }
+
 }