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.yangtools.yang.binding.RpcService;
+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.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private final RemoteDeviceId id;
private final ExecutorService executor;
- private volatile MountProvisionInstance mountInstance;
private volatile NetconfDeviceDatastoreAdapter datastoreAdapter;
+ private MountInstance mountInstance;
+
+ private volatile NetconfDeviceTopologyAdapter topologyDatastoreAdapter;
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;
}
return datastoreAdapter;
}
+ public NetconfDeviceTopologyAdapter getTopologyDatastoreAdapter() {
+ Preconditions.checkState(topologyDatastoreAdapter != null,
+ "%s: Sal provider %s was not initialized by sal. Cannot get topology datastore adapter", id);
+ return topologyDatastoreAdapter;
+ }
+
@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
return Collections.emptySet();
}
- @Override
- public Collection<? extends RpcService> getImplementations() {
- return Collections.emptySet();
- }
-
- @Override
- public Collection<? extends BindingAwareProvider.ProviderFunctionality> getFunctionality() {
- return Collections.emptySet();
- }
-
@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);
- }
- @Override
- public void onSessionInitialized(final BindingAwareBroker.ConsumerContext session) {
+ final DataBroker dataBroker = session.getSALService(DataBroker.class);
+ datastoreAdapter = new NetconfDeviceDatastoreAdapter(id, dataBroker);
+
+ topologyDatastoreAdapter = new NetconfDeviceTopologyAdapter(id, dataBroker);
}
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;
+
+ private ObjectRegistration<DOMMountPoint> topologyRegistration;
+
+ MountInstance(final DOMMountPointService mountService, final RemoteDeviceId id) {
+ this.mountService = Preconditions.checkNotNull(mountService);
+ this.id = Preconditions.checkNotNull(id);
+ }
+
+ @Deprecated
+ 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();
+ }
+
+ @Deprecated
+ 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;
+ }
+ }
+
+ synchronized void onTopologyDeviceConnected(final SchemaContext initialCtx,
+ final DOMDataBroker broker, final RpcProvisionRegistry rpc,
+ final NotificationPublishService notificationSerivce) {
+
+ Preconditions.checkNotNull(mountService, "Closed");
+ Preconditions.checkState(topologyRegistration == null, "Already initialized");
+
+ final DOMMountPointService.DOMMountPointBuilder mountBuilder = mountService.createMountPoint(id.getTopologyPath());
+ mountBuilder.addInitialSchemaContext(initialCtx);
+
+ mountBuilder.addService(DOMDataBroker.class, broker);
+ mountBuilder.addService(RpcProvisionRegistry.class, rpc);
+ this.notificationSerivce = notificationSerivce;
+ mountBuilder.addService(NotificationPublishService.class, notificationSerivce);
+
+ topologyRegistration = mountBuilder.register();
+ }
+
+ synchronized void onTopologyDeviceDisconnected() {
+ if(topologyRegistration == null) {
+ return;
+ }
+
+ try {
+ topologyRegistration.close();
+ } catch (final Exception e) {
+ // Only log and ignore
+ logger.warn("Unable to unregister mount instance for {}. Ignoring exception", id.getTopologyPath(), e);
+ } finally {
+ topologyRegistration = null;
+ }
+ }
+
+ @Override
+ synchronized public void close() throws Exception {
+ if(registration != null) {
+ onDeviceDisconnected();
+ onTopologyDeviceDisconnected();
+ }
+ mountService = null;
+ }
+
+ public synchronized void publish(final CompositeNode domNotification) {
+ Preconditions.checkNotNull(notificationSerivce, "Device not set up yet, cannot handle notification {}", domNotification);
+ notificationSerivce.publish(domNotification);
+ }
+ }
+
}