Bump upstreams
[bgpcep.git] / pcep / tunnel / tunnel-provider / src / main / java / org / opendaylight / bgpcep / pcep / tunnel / provider / PCEPTunnelClusterSingletonService.java
index 0bbf0a1f06dc28f741d14b9c33971b12c09249ab..43d148c8f119f30de78667053c129daf68e33e9b 100644 (file)
@@ -9,125 +9,133 @@ package org.opendaylight.bgpcep.pcep.tunnel.provider;
 
 import static java.util.Objects.requireNonNull;
 
-import com.google.common.util.concurrent.Futures;
+import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.ListenableFuture;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import javax.annotation.Nonnull;
-import javax.annotation.concurrent.GuardedBy;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import org.checkerframework.checker.lock.qual.GuardedBy;
 import org.opendaylight.bgpcep.programming.spi.InstructionScheduler;
 import org.opendaylight.bgpcep.topology.DefaultTopologyReference;
-import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
-import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
-import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.topology.rev140113.NetworkTopologyContext;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.TopologyTunnelPcepProgrammingService;
+import org.opendaylight.mdsal.common.api.CommitInfo;
+import org.opendaylight.mdsal.singleton.api.ClusterSingletonService;
+import org.opendaylight.mdsal.singleton.api.ServiceGroupIdentifier;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.ServiceTracker;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public final class PCEPTunnelClusterSingletonService implements ClusterSingletonService, AutoCloseable {
-
     private static final Logger LOG = LoggerFactory.getLogger(PCEPTunnelClusterSingletonService.class);
+
     private final PCEPTunnelTopologyProvider ttp;
     private final TunnelProgramming tp;
     private final ServiceGroupIdentifier sgi;
     private final TopologyId tunnelTopologyId;
-    private final TunnelProviderDependencies dependencies;
+
     @GuardedBy("this")
     private ServiceRegistration<?> serviceRegistration;
     @GuardedBy("this")
-    private ClusterSingletonServiceRegistration pcepTunnelCssReg;
+    private Registration pcepTunnelCssReg;
     @GuardedBy("this")
-    private BindingAwareBroker.RoutedRpcRegistration<TopologyTunnelPcepProgrammingService> reg;
+    private Registration reg;
 
     public PCEPTunnelClusterSingletonService(
             final TunnelProviderDependencies dependencies,
             final InstanceIdentifier<Topology> pcepTopology,
             final TopologyId tunnelTopologyId
     ) {
-        this.dependencies = requireNonNull(dependencies);
         this.tunnelTopologyId = requireNonNull(tunnelTopologyId);
         final TopologyId pcepTopologyId = pcepTopology.firstKeyOf(Topology.class).getTopologyId();
-
-        final WaitingServiceTracker<InstructionScheduler> schedulerTracker =
-                WaitingServiceTracker.create(InstructionScheduler.class,
-                        dependencies.getBundleContext(), "(" + InstructionScheduler.class.getName()
-                                + "=" + pcepTopologyId.getValue() + ")");
-        final InstructionScheduler scheduler = schedulerTracker.waitForService(WaitingServiceTracker.FIVE_MINUTES);
-        schedulerTracker.close();
+        final BundleContext bundleContext = dependencies.getBundleContext();
+
+        final InstructionScheduler scheduler;
+        ServiceTracker<InstructionScheduler, ?> tracker = null;
+        try {
+            tracker = new ServiceTracker<>(bundleContext,
+                bundleContext.createFilter("(&(%s=%s)%s)".formatted(
+                    Constants.OBJECTCLASS, InstructionScheduler.class.getName(),
+                    "(" + InstructionScheduler.class.getName() + "=" + pcepTopologyId.getValue() + ")")),
+                null);
+            tracker.open();
+            scheduler = (InstructionScheduler) tracker.waitForService(
+                    TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES));
+            Preconditions.checkState(scheduler != null, "InstructionScheduler service not found");
+        } catch (InvalidSyntaxException | InterruptedException e) {
+            throw new IllegalStateException("Error retrieving InstructionScheduler service", e);
+        } finally {
+            if (tracker != null) {
+                tracker.close();
+            }
+        }
 
         final InstanceIdentifier<Topology> tunnelTopology = InstanceIdentifier.builder(NetworkTopology.class)
                 .child(Topology.class, new TopologyKey(tunnelTopologyId)).build();
-        this.ttp = new PCEPTunnelTopologyProvider(dependencies.getDataBroker(), pcepTopology, pcepTopologyId,
+        ttp = new PCEPTunnelTopologyProvider(dependencies.getDataBroker(), pcepTopology, pcepTopologyId,
                 tunnelTopology, tunnelTopologyId);
 
 
-        this.sgi = scheduler.getIdentifier();
-        this.tp = new TunnelProgramming(scheduler, dependencies);
+        sgi = scheduler.getIdentifier();
+        tp = new TunnelProgramming(scheduler, dependencies);
 
 
-        final Dictionary<String, String> properties = new Hashtable<>();
-        properties.put(PCEPTunnelTopologyProvider.class.getName(), tunnelTopologyId.getValue());
-        this.serviceRegistration = dependencies.getBundleContext()
-                .registerService(DefaultTopologyReference.class.getName(), this.ttp, properties);
+        serviceRegistration = bundleContext.registerService(DefaultTopologyReference.class, ttp,
+            FrameworkUtil.asDictionary(Map.of(
+                PCEPTunnelTopologyProvider.class.getName(), tunnelTopologyId.getValue())));
 
-        LOG.info("PCEP Tunnel Cluster Singleton service {} registered", getIdentifier().getValue());
-        this.pcepTunnelCssReg = dependencies.getCssp().registerClusterSingletonService(this);
+        LOG.info("PCEP Tunnel Cluster Singleton service {} registered", getIdentifier().value());
+        pcepTunnelCssReg = dependencies.getCssp().registerClusterSingletonService(this);
     }
 
-
     @Override
     public synchronized void instantiateServiceInstance() {
-        LOG.info("Instantiate PCEP Tunnel Topology Provider Singleton Service {}", getIdentifier().getValue());
-        this.reg = this.dependencies.getRpcProviderRegistry()
-                .addRoutedRpcImplementation(TopologyTunnelPcepProgrammingService.class, this.tp);
-
-        final InstanceIdentifier<Topology> topology = InstanceIdentifier
-                .builder(NetworkTopology.class).child(Topology.class, new TopologyKey(this.tunnelTopologyId)).build();
-        this.reg.registerPath(NetworkTopologyContext.class, topology);
-        this.ttp.init();
+        LOG.info("Instantiate PCEP Tunnel Topology Provider Singleton Service {}", getIdentifier().value());
+
+        reg = tp.register(InstanceIdentifier.builder(NetworkTopology.class)
+            .child(Topology.class, new TopologyKey(tunnelTopologyId))
+            .build());
+        ttp.init();
     }
 
     @Override
-    public synchronized ListenableFuture<Void> closeServiceInstance() {
-        LOG.info("Close Service Instance PCEP Tunnel Topology Provider Singleton Service {}",
-                getIdentifier().getValue());
-        this.reg.close();
-        this.tp.close();
-        this.ttp.close();
-        return Futures.immediateFuture(null);
+    public synchronized ListenableFuture<? extends CommitInfo> closeServiceInstance() {
+        LOG.info("Close Service Instance PCEP Tunnel Topology Provider Singleton Service {}", getIdentifier().value());
+        reg.close();
+        tp.close();
+        ttp.close();
+        return CommitInfo.emptyFluentFuture();
     }
 
-    @Nonnull
     @Override
     public ServiceGroupIdentifier getIdentifier() {
-        return this.sgi;
+        return sgi;
     }
 
     @Override
     @SuppressWarnings("checkstyle:IllegalCatch")
     public synchronized void close() {
-        LOG.info("Close PCEP Tunnel Topology Provider Singleton Service {}", getIdentifier().getValue());
+        LOG.info("Close PCEP Tunnel Topology Provider Singleton Service {}", getIdentifier().value());
 
-        if (this.pcepTunnelCssReg != null) {
+        if (pcepTunnelCssReg != null) {
             try {
-                this.pcepTunnelCssReg.close();
+                pcepTunnelCssReg.close();
             } catch (final Exception e) {
-                LOG.debug("Failed to close PCEP Tunnel Topology service {}", this.sgi.getValue(), e);
+                LOG.debug("Failed to close PCEP Tunnel Topology service {}", sgi.value(), e);
             }
-            this.pcepTunnelCssReg = null;
+            pcepTunnelCssReg = null;
         }
-        if (this.serviceRegistration != null) {
-            this.serviceRegistration.unregister();
-            this.serviceRegistration = null;
+        if (serviceRegistration != null) {
+            serviceRegistration.unregister();
+            serviceRegistration = null;
         }
     }
 }