BUG-6973: Wire topology-provider with BP 14/53414/5
authorClaudio D. Gasparini <claudio.gasparini@pantheon.tech>
Thu, 2 Mar 2017 11:22:47 +0000 (12:22 +0100)
committerRobert Varga <nite@hq.sk>
Wed, 12 Apr 2017 22:28:57 +0000 (22:28 +0000)
-Wire topology-provider with BP
-Preserve backwards compatibility

Change-Id: Ibc459117b1656a0efe5e34365b9fc131479bdaea
Signed-off-by: Claudio D. Gasparini <claudio.gasparini@pantheon.tech>
14 files changed:
pcep/topology-provider/pom.xml
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/PCEPTopologyProvider.java
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/ServerSessionManager.java
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/config/PCEPTopologyDeployer.java [new file with mode: 0644]
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/config/PCEPTopologyDeployerImpl.java [new file with mode: 0644]
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/config/PCEPTopologyProviderBean.java [new file with mode: 0644]
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/config/PCEPTopologyProviderDependenciesProvider.java [new file with mode: 0644]
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/config/PCEPTopologyProviderUtil.java [new file with mode: 0644]
pcep/topology-provider/src/main/java/org/opendaylight/controller/config/yang/pcep/topology/provider/PCEPTopologyProviderModule.java
pcep/topology-provider/src/main/java/org/opendaylight/controller/config/yang/pcep/topology/provider/PCEPTopologyProviderModuleFactory.java
pcep/topology-provider/src/main/java/org/opendaylight/controller/config/yang/pcep/topology/provider/Stateful07TopologySessionListenerModule.java
pcep/topology-provider/src/main/java/org/opendaylight/controller/config/yang/pcep/topology/provider/Stateful07TopologySessionListenerModuleFactory.java
pcep/topology-provider/src/main/resources/org/opendaylight/blueprint/pcep-topology.xml [new file with mode: 0644]
pcep/topology-provider/src/test/java/org/opendaylight/bgpcep/pcep/topology/provider/AbstractPCEPSessionTest.java

index 51359fe5507e59118e11c6cd36cf44d44c51c0ba..aa0aa11e2e90ed824122d73ebaff33eee70a1e1e 100644 (file)
             <artifactId>org.osgi.core</artifactId>
             <scope>provided</scope>
         </dependency>
-
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
         <!-- Test dependencies -->
         <dependency>
             <groupId>junit</groupId>
index e64a05b59a7700aefdb875e409087d2491eb5262..d15704f1f604e599f7367e35f30247747e08abbc 100755 (executable)
@@ -13,33 +13,37 @@ import io.netty.channel.Channel;
 import io.netty.channel.ChannelFuture;
 import java.net.InetSocketAddress;
 import java.util.List;
-import java.util.concurrent.ExecutionException;
+import org.opendaylight.bgpcep.pcep.topology.provider.config.PCEPTopologyProviderDependenciesProvider;
 import org.opendaylight.bgpcep.programming.spi.InstructionScheduler;
 import org.opendaylight.bgpcep.topology.DefaultTopologyReference;
 import org.opendaylight.controller.config.yang.pcep.topology.provider.PCEPTopologyProviderRuntimeRegistrator;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.protocol.concepts.KeyMapping;
 import org.opendaylight.protocol.pcep.PCEPCapability;
-import org.opendaylight.protocol.pcep.PCEPDispatcher;
 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.pcep.programming.rev131106.NetworkTopologyPcepProgrammingService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.NetworkTopologyPcepService;
+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.yang.binding.InstanceIdentifier;
+import org.osgi.framework.ServiceRegistration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public final class PCEPTopologyProvider extends DefaultTopologyReference implements AutoCloseable {
 
     private static final Logger LOG = LoggerFactory.getLogger(PCEPTopologyProvider.class);
+
+    private static final String STATEFUL_NOT_DEFINED = "Stateful capability not defined, aborting PCEP Topology" +
+        " Provider instantiation";
     private final BindingAwareBroker.RoutedRpcRegistration<NetworkTopologyPcepProgrammingService> network;
     private final BindingAwareBroker.RoutedRpcRegistration<NetworkTopologyPcepService> element;
     private final ServerSessionManager manager;
     private final Channel channel;
+    private ServiceRegistration<?> serviceRegistration;
 
     private PCEPTopologyProvider(final Channel channel, final InstanceIdentifier<Topology> topology, final ServerSessionManager manager,
             final BindingAwareBroker.RoutedRpcRegistration<NetworkTopologyPcepService> element,
@@ -51,12 +55,12 @@ public final class PCEPTopologyProvider extends DefaultTopologyReference impleme
         this.network = Preconditions.checkNotNull(network);
     }
 
-    public static PCEPTopologyProvider create(final PCEPDispatcher dispatcher, final InetSocketAddress address, final Optional<KeyMapping> keys,
-            final InstructionScheduler scheduler, final DataBroker dataBroker, final RpcProviderRegistry rpcRegistry,
-            final InstanceIdentifier<Topology> topology, final TopologySessionListenerFactory listenerFactory,
-            final Optional<PCEPTopologyProviderRuntimeRegistrator> runtimeRootRegistrator, final int rpcTimeout) throws InterruptedException,
-            ExecutionException, ReadFailedException, TransactionCommitFailedException {
-        List<PCEPCapability> capabilities = dispatcher.getPCEPSessionNegotiatorFactory().getPCEPSessionProposalFactory().getCapabilities();
+    public static PCEPTopologyProvider create(final PCEPTopologyProviderDependenciesProvider dependenciesProvider,
+        final InetSocketAddress address, final Optional<KeyMapping> keys, final InstructionScheduler scheduler,
+        final TopologyId topologyId, final Optional<PCEPTopologyProviderRuntimeRegistrator> runtimeRootRegistrator,
+        final int rpcTimeout) throws Exception {
+        final List<PCEPCapability> capabilities = dependenciesProvider.getPCEPDispatcher()
+            .getPCEPSessionNegotiatorFactory().getPCEPSessionProposalFactory().getCapabilities();
         boolean statefulCapability = false;
         for (final PCEPCapability capability : capabilities) {
             if (capability.isStateful()) {
@@ -64,34 +68,41 @@ public final class PCEPTopologyProvider extends DefaultTopologyReference impleme
                 break;
             }
         }
+
+        final TopologySessionListenerFactory listenerFactory = dependenciesProvider.getTopologySessionListenerFactory();
         if (!statefulCapability && listenerFactory != null) {
-            throw new IllegalStateException("Stateful capability not defined, aborting PCEP Topology Provider instantiation");
+            throw new IllegalStateException(STATEFUL_NOT_DEFINED);
         }
 
-        final ServerSessionManager manager = new ServerSessionManager(dataBroker, topology, listenerFactory, rpcTimeout);
-        if (runtimeRootRegistrator.isPresent()) {
-            manager.setRuntimeRootRegistartion(runtimeRootRegistrator.get());
+        final InstanceIdentifier<Topology> topology = InstanceIdentifier.builder(NetworkTopology.class)
+            .child(Topology.class, new TopologyKey(topologyId)).build();
+        final ServerSessionManager manager = new ServerSessionManager(dependenciesProvider.getDataBroker(), topology,
+            listenerFactory, rpcTimeout);
+        if(runtimeRootRegistrator.isPresent()){
+            manager.setRuntimeRootRegistrator(runtimeRootRegistrator.get());
         }
-        final ChannelFuture f = dispatcher.createServer(address, keys, manager, manager);
+        final ChannelFuture f = dependenciesProvider.getPCEPDispatcher().createServer(address, keys, manager, manager);
         f.get();
 
-        final BindingAwareBroker.RoutedRpcRegistration<NetworkTopologyPcepService> element = rpcRegistry.addRoutedRpcImplementation(
-                NetworkTopologyPcepService.class, new TopologyRPCs(manager));
+        final RpcProviderRegistry rpcRegistry = dependenciesProvider.getRpcProviderRegistry();
+        final BindingAwareBroker.RoutedRpcRegistration<NetworkTopologyPcepService> element = rpcRegistry
+            .addRoutedRpcImplementation(NetworkTopologyPcepService.class, new TopologyRPCs(manager));
         element.registerPath(NetworkTopologyContext.class, topology);
 
-        final BindingAwareBroker.RoutedRpcRegistration<NetworkTopologyPcepProgrammingService> network = rpcRegistry.addRoutedRpcImplementation(
-                NetworkTopologyPcepProgrammingService.class, new TopologyProgramming(scheduler, manager));
+        final BindingAwareBroker.RoutedRpcRegistration<NetworkTopologyPcepProgrammingService> network = rpcRegistry
+            .addRoutedRpcImplementation(NetworkTopologyPcepProgrammingService.class,
+                new TopologyProgramming(scheduler, manager));
         network.registerPath(NetworkTopologyContext.class, topology);
 
         return new PCEPTopologyProvider(f.channel(), topology, manager, element, network);
     }
 
     @Override
-    public void close() throws InterruptedException {
+    public void close() {
         try {
             this.channel.close().sync();
             LOG.debug("Server channel {} closed", this.channel);
-        } catch (InterruptedException e) {
+        } catch (final InterruptedException e) {
             LOG.error("Failed to close channel {}", this.channel, e);
         }
 
@@ -110,5 +121,13 @@ public final class PCEPTopologyProvider extends DefaultTopologyReference impleme
         } catch (final Exception e) {
             LOG.error("Failed to shutdown session manager", e);
         }
+        if (this.serviceRegistration != null) {
+            this.serviceRegistration.unregister();
+            this.serviceRegistration = null;
+        }
+    }
+
+    public synchronized void setServiceRegistration(final ServiceRegistration<?> serviceRegistration) {
+        this.serviceRegistration = serviceRegistration;
     }
 }
index 26b1dc6c2dcf8ba6a0ff1545c23ea631b2194e38..4bf1bc4e872c4e208679c88f3640176badde6aed 100755 (executable)
@@ -191,13 +191,13 @@ final class ServerSessionManager implements PCEPSessionListenerFactory, AutoClos
         t.submit().checkedGet();
     }
 
-    public void setRuntimeRootRegistartion(final PCEPTopologyProviderRuntimeRegistrator runtimeRootRegistrator) {
+    synchronized void setRuntimeRootRegistrator(final PCEPTopologyProviderRuntimeRegistrator runtimeRootRegistrator) {
         if (!this.runtimeRootRegistration.compareAndSet(null, runtimeRootRegistrator.register(this))) {
             LOG.error("Runtime root registration has been set before.");
         }
     }
 
-    public ListenerStateRuntimeRegistration registerRuntimeRootRegistration(final ListenerStateRuntimeMXBean bean) {
+    ListenerStateRuntimeRegistration registerRuntimeRootRegistration(final ListenerStateRuntimeMXBean bean) {
         final PCEPTopologyProviderRuntimeRegistration runtimeReg = this.runtimeRootRegistration.get();
         if (runtimeReg != null) {
             final ListenerStateRuntimeRegistration reg = runtimeReg.register(bean);
@@ -210,7 +210,7 @@ final class ServerSessionManager implements PCEPSessionListenerFactory, AutoClos
     @Override
     public void setPeerSpecificProposal(final InetSocketAddress address, final TlvsBuilder openBuilder) {
         Preconditions.checkNotNull(address);
-        peerProposal.setPeerProposal(createNodeId(address.getAddress()), openBuilder);
+        this.peerProposal.setPeerProposal(createNodeId(address.getAddress()), openBuilder);
     }
 
     public int getRpcTimeout() {
diff --git a/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/config/PCEPTopologyDeployer.java b/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/config/PCEPTopologyDeployer.java
new file mode 100644 (file)
index 0000000..f98ece6
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.bgpcep.pcep.topology.provider.config;
+
+import com.google.common.base.Optional;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.bgpcep.programming.spi.InstructionScheduler;
+import org.opendaylight.controller.config.yang.pcep.topology.provider.PCEPTopologyProviderRuntimeRegistrator;
+import org.opendaylight.protocol.concepts.KeyMapping;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+
+/**
+ * The PCEPTopologyDeployer service is managing PcepTopologyProvider
+ */
+public interface PCEPTopologyDeployer {
+    /**
+     * Creates and register topology provider instance
+     *  @param topologyId topology ID
+     * @param inetSocketAddress inetSocketAddress
+     * @param rpcTimeout rpc Timeout
+     * @param client List of clients password configuration
+     * @param scheduler  Instruction Scheduler
+     */
+    void createTopologyProvider(@Nonnull TopologyId topologyId, @Nonnull InetSocketAddress inetSocketAddress,
+        short rpcTimeout, @Nullable Optional<KeyMapping> client, @Nonnull InstructionScheduler scheduler,
+        Optional<PCEPTopologyProviderRuntimeRegistrator> runtime);
+
+    /**
+     * Closes and unregister topology provider instance
+     *
+     * @param topologyID topology ID
+     */
+    void removeTopologyProvider(@Nonnull TopologyId topologyID);
+}
diff --git a/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/config/PCEPTopologyDeployerImpl.java b/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/config/PCEPTopologyDeployerImpl.java
new file mode 100644 (file)
index 0000000..78587a4
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.bgpcep.pcep.topology.provider.config;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import java.net.InetSocketAddress;
+import java.util.HashMap;
+import java.util.Map;
+import javax.annotation.concurrent.GuardedBy;
+import org.opendaylight.bgpcep.programming.spi.InstructionScheduler;
+import org.opendaylight.controller.config.yang.pcep.topology.provider.PCEPTopologyProviderRuntimeRegistrator;
+import org.opendaylight.protocol.concepts.KeyMapping;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PCEPTopologyDeployerImpl implements PCEPTopologyDeployer, AutoCloseable {
+    private static final Logger LOG = LoggerFactory.getLogger(PCEPTopologyDeployerImpl.class);
+
+    @GuardedBy("this")
+    private final Map<TopologyId, PCEPTopologyProviderBean> pcepTopologyServices = new HashMap<>();
+    private final BlueprintContainer container;
+
+    public PCEPTopologyDeployerImpl(final BlueprintContainer container) {
+        this.container = Preconditions.checkNotNull(container);
+    }
+
+    @Override
+    public synchronized void createTopologyProvider(final TopologyId topologyId,
+        final InetSocketAddress inetSocketAddress, final short rpcTimeout, final Optional<KeyMapping> keys,
+        final InstructionScheduler schedulerDependency,
+        final Optional<PCEPTopologyProviderRuntimeRegistrator> runtime) {
+        if (this.pcepTopologyServices.containsKey(topologyId)) {
+            LOG.warn("Topology Provider {} already exist. New instance won't be created", topologyId);
+            return;
+        }
+        final PCEPTopologyProviderBean PCEPTopologyProviderBean = (PCEPTopologyProviderBean) this.container
+            .getComponentInstance(PCEPTopologyProviderBean.class.getSimpleName());
+        this.pcepTopologyServices.put(topologyId, PCEPTopologyProviderBean);
+        PCEPTopologyProviderBean.start(inetSocketAddress, keys, schedulerDependency, topologyId,
+            runtime, rpcTimeout);
+    }
+
+    @Override
+    public synchronized void removeTopologyProvider(final TopologyId topologyID) {
+        final PCEPTopologyProviderBean service = this.pcepTopologyServices.remove(topologyID);
+        if (service != null) {
+            service.close();
+        }
+    }
+
+    @Override
+    public synchronized void close() throws Exception {
+        this.pcepTopologyServices.values().forEach(PCEPTopologyProviderBean::close);
+    }
+}
diff --git a/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/config/PCEPTopologyProviderBean.java b/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/config/PCEPTopologyProviderBean.java
new file mode 100644 (file)
index 0000000..3077d23
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.bgpcep.pcep.topology.provider.config;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import java.net.InetSocketAddress;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+import org.opendaylight.bgpcep.pcep.topology.provider.PCEPTopologyProvider;
+import org.opendaylight.bgpcep.pcep.topology.provider.TopologySessionListenerFactory;
+import org.opendaylight.bgpcep.programming.spi.InstructionScheduler;
+import org.opendaylight.bgpcep.topology.DefaultTopologyReference;
+import org.opendaylight.controller.config.yang.pcep.topology.provider.PCEPTopologyProviderRuntimeRegistrator;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.protocol.concepts.KeyMapping;
+import org.opendaylight.protocol.pcep.PCEPCapability;
+import org.opendaylight.protocol.pcep.PCEPDispatcher;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class PCEPTopologyProviderBean implements PCEPTopologyProviderDependenciesProvider, AutoCloseable {
+    private static final Logger LOG = LoggerFactory.getLogger(PCEPTopologyProviderBean.class);
+
+    private static final String STATEFUL_NOT_DEFINED = "Stateful capability not defined, aborting PCEP Topology " +
+        "Deployer instantiation";
+    private final PCEPDispatcher pcepDispatcher;
+    private final DataBroker dataBroker;
+    private final TopologySessionListenerFactory sessionListenerFactory;
+    private final RpcProviderRegistry rpcProviderRegistry;
+    private final BundleContext bundleContext;
+    private PCEPTopologyProvider pcepTopoProvider;
+
+    public PCEPTopologyProviderBean(final BundleContext bundleContext, final DataBroker dataBroker,
+        final PCEPDispatcher pcepDispatcher, final RpcProviderRegistry rpcProviderRegistry,
+        final TopologySessionListenerFactory sessionListenerFactory) {
+        this.bundleContext = Preconditions.checkNotNull(bundleContext);
+        this.pcepDispatcher = Preconditions.checkNotNull(pcepDispatcher);
+        this.dataBroker = Preconditions.checkNotNull(dataBroker);
+        this.sessionListenerFactory = Preconditions.checkNotNull(sessionListenerFactory);
+        this.rpcProviderRegistry = Preconditions.checkNotNull(rpcProviderRegistry);
+        final List<PCEPCapability> capabilities = this.pcepDispatcher.getPCEPSessionNegotiatorFactory()
+            .getPCEPSessionProposalFactory().getCapabilities();
+        final boolean statefulCapability = capabilities.stream().anyMatch(PCEPCapability::isStateful);
+        if (!statefulCapability) {
+            throw new IllegalStateException(STATEFUL_NOT_DEFINED);
+        }
+    }
+
+    @Override
+    public void close() {
+        if (this.pcepTopoProvider != null) {
+            this.pcepTopoProvider.close();
+        }
+    }
+
+    public void start(final InetSocketAddress inetSocketAddress, final Optional<KeyMapping> keys,
+        final InstructionScheduler schedulerDependency, final TopologyId topologyId,
+        final Optional<PCEPTopologyProviderRuntimeRegistrator> runtime, final short rpcTimeout) {
+        Preconditions.checkState(this.pcepTopoProvider == null,
+            "Previous instance %s was not closed.", this);
+        try {
+            this.pcepTopoProvider = PCEPTopologyProvider.create(this,
+                inetSocketAddress, keys, schedulerDependency, topologyId, runtime, rpcTimeout);
+
+            final Dictionary<String, String> properties = new Hashtable<>();
+            properties.put(PCEPTopologyProvider.class.getName(), topologyId.getValue());
+            final ServiceRegistration<?> serviceRegistration = this.bundleContext
+                .registerService(DefaultTopologyReference.class.getName(), this.pcepTopoProvider, properties);
+            this.pcepTopoProvider.setServiceRegistration(serviceRegistration);
+        } catch (final Exception e) {
+            LOG.debug("Failed to create PCEPTopologyProvider {}", topologyId.getValue());
+        }
+    }
+
+    @Override
+    public PCEPDispatcher getPCEPDispatcher() {
+        return this.pcepDispatcher;
+    }
+
+    @Override
+    public RpcProviderRegistry getRpcProviderRegistry() {
+        return this.rpcProviderRegistry;
+    }
+
+    @Override
+    public DataBroker getDataBroker() {
+        return this.dataBroker;
+    }
+
+    @Override
+    public TopologySessionListenerFactory getTopologySessionListenerFactory() {
+        return this.sessionListenerFactory;
+    }
+}
diff --git a/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/config/PCEPTopologyProviderDependenciesProvider.java b/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/config/PCEPTopologyProviderDependenciesProvider.java
new file mode 100644 (file)
index 0000000..bb63b27
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.bgpcep.pcep.topology.provider.config;
+
+import org.opendaylight.bgpcep.pcep.topology.provider.TopologySessionListenerFactory;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.protocol.pcep.PCEPDispatcher;
+
+/**
+ * Provides required dependencies for PCEPTopologyProviderProvider instantiation
+ */
+public interface PCEPTopologyProviderDependenciesProvider {
+    /**
+     *
+     * @return PCEPDispatcher
+     */
+    PCEPDispatcher getPCEPDispatcher();
+
+    /**
+     *
+     * @return RpcProviderRegistry
+     */
+    RpcProviderRegistry getRpcProviderRegistry();
+
+    /**
+     *
+     * @return DataBroker
+     */
+    DataBroker getDataBroker();
+
+    /**
+     *
+     * @return TopologySessionListenerFactory
+     */
+    TopologySessionListenerFactory getTopologySessionListenerFactory();
+}
diff --git a/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/config/PCEPTopologyProviderUtil.java b/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/config/PCEPTopologyProviderUtil.java
new file mode 100644 (file)
index 0000000..f8b705e
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.bgpcep.pcep.topology.provider.config;
+
+import com.google.common.base.Optional;
+import com.google.common.net.InetAddresses;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import org.opendaylight.controller.config.yang.pcep.topology.provider.Client;
+import org.opendaylight.protocol.concepts.KeyMapping;
+import org.opendaylight.protocol.util.Ipv4Util;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.rfc2385.cfg.rev160324.Rfc2385Key;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class PCEPTopologyProviderUtil {
+    private static final Logger LOG = LoggerFactory.getLogger(PCEPTopologyProviderUtil.class);
+
+    private PCEPTopologyProviderUtil() {
+        throw new UnsupportedOperationException();
+    }
+
+    public static Optional<KeyMapping> contructKeys(final List<Client> clients) {
+        KeyMapping ret = null;
+
+        if (clients != null && !clients.isEmpty()) {
+            ret = KeyMapping.getKeyMapping();
+            for (final Client c : clients) {
+                if (c.getAddress() == null) {
+                    LOG.warn("Client {} does not have an address skipping it", c);
+                    continue;
+                }
+                final Rfc2385Key rfc2385KeyPassword = c.getPassword();
+                if (rfc2385KeyPassword != null && !rfc2385KeyPassword.getValue().isEmpty()) {
+                    final String s = Ipv4Util.toStringIP(c.getAddress());
+                    ret.put(InetAddresses.forString(s), rfc2385KeyPassword.getValue().getBytes(StandardCharsets.US_ASCII));
+                }
+            }
+        }
+        return Optional.fromNullable(ret);
+    }
+}
index e9b845ad1e4c5d4ea2b9cd95f5fc151919dd2fb1..150163cb0df5c268ab97362ee3ec960d8030209a 100755 (executable)
  */
 package org.opendaylight.controller.config.yang.pcep.topology.provider;
 
+import static org.opendaylight.bgpcep.pcep.topology.provider.config.PCEPTopologyProviderUtil.contructKeys;
+
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.net.InetAddresses;
+import com.google.common.reflect.AbstractInvocationHandler;
+import com.google.common.reflect.Reflection;
 import io.netty.channel.epoll.Epoll;
+import java.lang.reflect.Method;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
 import org.opendaylight.bgpcep.pcep.topology.provider.PCEPTopologyProvider;
+import org.opendaylight.bgpcep.pcep.topology.provider.config.PCEPTopologyDeployer;
+import org.opendaylight.bgpcep.topology.DefaultTopologyReference;
+import org.opendaylight.bgpcep.topology.TopologyReference;
 import org.opendaylight.controller.config.api.JmxAttributeValidationException;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker;
 import org.opendaylight.protocol.concepts.KeyMapping;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.rfc2385.cfg.rev160324.Rfc2385Key;
-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.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.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.osgi.framework.BundleContext;
 
 /**
- *
+ * @deprecated
  */
 public final class PCEPTopologyProviderModule extends
-        org.opendaylight.controller.config.yang.pcep.topology.provider.AbstractPCEPTopologyProviderModule {
-    private static final Logger LOG = LoggerFactory.getLogger(PCEPTopologyProviderModule.class);
+    org.opendaylight.controller.config.yang.pcep.topology.provider.AbstractPCEPTopologyProviderModule {
 
     private static final String IS_NOT_SET = "is not set.";
+    private static final String NATIVE_TRANSPORT_NOT_AVAILABLE = "Client is configured with password but native" +
+        " transport is not available";
+    private BundleContext bundleContext;
 
     public PCEPTopologyProviderModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier,
-            final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
         super(identifier, dependencyResolver);
     }
 
     public PCEPTopologyProviderModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier,
-            final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, final PCEPTopologyProviderModule oldModule,
-            final java.lang.AutoCloseable oldInstance) {
+        final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+        final PCEPTopologyProviderModule oldModule, final java.lang.AutoCloseable oldInstance) {
         super(identifier, dependencyResolver, oldModule, oldInstance);
     }
 
-    private Optional<KeyMapping> contructKeys() {
-        KeyMapping ret = null;
-        final List<Client> clients = getClient();
-
-        if (clients != null && !clients.isEmpty()) {
-            ret = KeyMapping.getKeyMapping();
-            for (final Client c : clients) {
-                if (c.getAddress() == null) {
-                    LOG.warn("Client {} does not have an address skipping it", c);
-                    continue;
-                }
-                final Rfc2385Key rfc2385KeyPassword = c.getPassword();
-                if (rfc2385KeyPassword != null && !rfc2385KeyPassword.getValue().isEmpty()) {
-                    final String s = getAddressString(c.getAddress());
-                    ret.put(InetAddresses.forString(s), rfc2385KeyPassword.getValue().getBytes(StandardCharsets.US_ASCII));
-                }
-            }
-        }
-        return Optional.fromNullable(ret);
-    }
-
-
-    private String getAddressString(final IpAddress address) {
-        Preconditions.checkArgument(address.getIpv4Address() != null || address.getIpv6Address() != null, "Address %s is invalid", address);
-        if (address.getIpv4Address() != null) {
-            return address.getIpv4Address().getValue();
-        }
-        return address.getIpv6Address().getValue();
-    }
-
-
     @Override
     public void customValidation() {
         JmxAttributeValidationException.checkNotNull(getTopologyId(), IS_NOT_SET, topologyIdJmxAttribute);
@@ -98,16 +68,17 @@ public final class PCEPTopologyProviderModule extends
         JmxAttributeValidationException.checkNotNull(getStatefulPlugin(), IS_NOT_SET, statefulPluginJmxAttribute);
         JmxAttributeValidationException.checkNotNull(getRpcTimeout(), IS_NOT_SET, rpcTimeoutJmxAttribute);
 
-        final Optional<KeyMapping> keys = contructKeys();
+        final Optional<KeyMapping> keys = contructKeys(getClient());
         if (keys.isPresent()) {
-            JmxAttributeValidationException.checkCondition(Epoll.isAvailable(),
-                    "client is configured with password but native transport is not available", clientJmxAttribute);
+            JmxAttributeValidationException.checkCondition(Epoll.isAvailable(), NATIVE_TRANSPORT_NOT_AVAILABLE,
+                clientJmxAttribute);
         }
     }
 
     private InetAddress listenAddress() {
         final IpAddress a = getListenAddress();
-        Preconditions.checkArgument(a.getIpv4Address() != null || a.getIpv6Address() != null, "Address %s not supported", a);
+        Preconditions.checkArgument(a.getIpv4Address() != null || a.getIpv6Address() != null,
+            "Address %s not supported", a);
         if (a.getIpv4Address() != null) {
             return InetAddresses.forString(a.getIpv4Address().getValue());
         }
@@ -116,17 +87,46 @@ public final class PCEPTopologyProviderModule extends
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        final InstanceIdentifier<Topology> topology = InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class,
-                new TopologyKey(getTopologyId())).build();
-        final InetSocketAddress address = new InetSocketAddress(listenAddress(), getListenPort().getValue());
-
-        try {
-            return PCEPTopologyProvider.create(getDispatcherDependency(), address, contructKeys(), getSchedulerDependency(),
-                    getDataProviderDependency(), getRpcRegistryDependency(), topology, getStatefulPluginDependency(),
-                    Optional.of(getRootRuntimeBeanRegistratorWrapper()), getRpcTimeout());
-        } catch (InterruptedException | ExecutionException | TransactionCommitFailedException | ReadFailedException e) {
-            LOG.error("Failed to instantiate topology provider at {}", address, e);
-            throw new IllegalStateException("Failed to instantiate provider", e);
-        }
+        final WaitingServiceTracker<PCEPTopologyDeployer> pcepcTopologyDeployerTracker =
+            WaitingServiceTracker.create(PCEPTopologyDeployer.class, this.bundleContext);
+        final PCEPTopologyDeployer pcepcTopologyDeployer = pcepcTopologyDeployerTracker
+            .waitForService(WaitingServiceTracker.FIVE_MINUTES);
+
+        final TopologyId topologyID = getTopologyId();
+        final com.google.common.base.Optional<KeyMapping> keys = contructKeys(getClient());
+
+        final InetSocketAddress inetSocketAddress = new InetSocketAddress(listenAddress(), getListenPort().getValue());
+
+        pcepcTopologyDeployer.createTopologyProvider(topologyID, inetSocketAddress, getRpcTimeout(), keys,
+            getSchedulerDependency(), Optional.fromNullable(getRootRuntimeBeanRegistratorWrapper()));
+
+        final WaitingServiceTracker<DefaultTopologyReference> defaultTopologyReferenceTracker =
+            WaitingServiceTracker.create(DefaultTopologyReference.class, this.bundleContext,
+                "(" + PCEPTopologyProvider.class.getName() + "=" + topologyID.getValue() + ")");
+        final DefaultTopologyReference defaultTopologyReference = defaultTopologyReferenceTracker
+            .waitForService(WaitingServiceTracker.FIVE_MINUTES);
+
+        return Reflection.newProxy(PcepTopologyProviderCloseable.class, new AbstractInvocationHandler() {
+            @Override
+            protected Object handleInvocation(final Object proxy, final Method method, final Object[] args)
+                throws Throwable {
+                if (method.getName().equals("close")) {
+                    pcepcTopologyDeployer.removeTopologyProvider(topologyID);
+                    pcepcTopologyDeployerTracker.close();
+                    defaultTopologyReferenceTracker.close();
+                    return null;
+                } else {
+                    return method.invoke(defaultTopologyReference, args);
+                }
+            }
+        });
+    }
+
+    void setBundleContext(final BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
+
+    private interface PcepTopologyProviderCloseable extends TopologyReference, AutoCloseable {
+
     }
 }
index e67fd1b9441d40774148449ec5cda50674a73ed0..74472260b8e4bc994be78880f3818734e022aa8c 100644 (file)
  */
 package org.opendaylight.controller.config.yang.pcep.topology.provider;
 
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
+import org.opendaylight.controller.config.spi.Module;
+import org.osgi.framework.BundleContext;
+
 /**
-*
-*/
+ * @deprecated
+ */
 public class PCEPTopologyProviderModuleFactory extends
-        org.opendaylight.controller.config.yang.pcep.topology.provider.AbstractPCEPTopologyProviderModuleFactory {
+    org.opendaylight.controller.config.yang.pcep.topology.provider.AbstractPCEPTopologyProviderModuleFactory {
+    @Override
+    public Module createModule(final String instanceName, final DependencyResolver dependencyResolver,
+        final BundleContext bundleContext) {
+        final PCEPTopologyProviderModule module = (PCEPTopologyProviderModule)
+            super.createModule(instanceName, dependencyResolver, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
 
+    @Override
+    public Module createModule(final String instanceName, final DependencyResolver dependencyResolver,
+        final DynamicMBeanWithInstance old, final BundleContext bundleContext) throws Exception {
+        final PCEPTopologyProviderModule module = (PCEPTopologyProviderModule)
+            super.createModule(instanceName, dependencyResolver, old, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
 }
index 82218992350e7de9cc8262e9dac337de2ae47b39..0547a48f832b8323a8bfe199e88656316b74ce03 100644 (file)
  */
 package org.opendaylight.controller.config.yang.pcep.topology.provider;
 
-import org.opendaylight.bgpcep.pcep.topology.provider.Stateful07TopologySessionListenerFactory;
+import com.google.common.reflect.AbstractInvocationHandler;
+import com.google.common.reflect.Reflection;
+import java.lang.reflect.Method;
+import org.opendaylight.bgpcep.pcep.topology.provider.TopologySessionListenerFactory;
+import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker;
+import org.osgi.framework.BundleContext;
 
 /**
- *
+ * @deprecated Replaced by blueprint wiring
  */
 public final class Stateful07TopologySessionListenerModule extends
         org.opendaylight.controller.config.yang.pcep.topology.provider.AbstractStateful07TopologySessionListenerModule {
+    private BundleContext bundleContext;
 
     public Stateful07TopologySessionListenerModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier,
             final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
@@ -32,7 +38,6 @@ public final class Stateful07TopologySessionListenerModule extends
     public Stateful07TopologySessionListenerModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier,
             final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
             final Stateful07TopologySessionListenerModule oldModule, final java.lang.AutoCloseable oldInstance) {
-
         super(identifier, dependencyResolver, oldModule, oldInstance);
     }
 
@@ -43,14 +48,27 @@ public final class Stateful07TopologySessionListenerModule extends
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        return new AutoCloseableStateful07TopologySessionListenerFactory();
+        final WaitingServiceTracker<TopologySessionListenerFactory> tracker = WaitingServiceTracker
+            .create(TopologySessionListenerFactory.class, this.bundleContext);
+        final TopologySessionListenerFactory service = tracker.waitForService(WaitingServiceTracker.FIVE_MINUTES);
+
+        return Reflection.newProxy(AutoCloseableService.class, new AbstractInvocationHandler() {
+            @Override
+            protected Object handleInvocation(final Object proxy, final Method method, final Object[] args) throws Throwable {
+                if (method.getName().equals("close")) {
+                    tracker.close();
+                    return null;
+                } else {
+                    return method.invoke(service, args);
+                }
+            }
+        });
+    }
+
+    void setBundleContext(final BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
     }
 
-    private static final class AutoCloseableStateful07TopologySessionListenerFactory extends Stateful07TopologySessionListenerFactory
-            implements AutoCloseable {
-        @Override
-        public void close() {
-            // Nothing to do
-        }
+    private interface AutoCloseableService extends TopologySessionListenerFactory, AutoCloseable {
     }
 }
index 17a4e07facfb34bd41cea3e27d65622b4ea419c7..1dbb655cdde457bbda5f54c6d95735736d9f6dc7 100644 (file)
  */
 package org.opendaylight.controller.config.yang.pcep.topology.provider;
 
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
+import org.opendaylight.controller.config.spi.Module;
+import org.osgi.framework.BundleContext;
+
 /**
-*
-*/
+ * @deprecated Replaced by blueprint wiring
+ */
 public class Stateful07TopologySessionListenerModuleFactory extends
-        org.opendaylight.controller.config.yang.pcep.topology.provider.AbstractStateful07TopologySessionListenerModuleFactory {
+    AbstractStateful07TopologySessionListenerModuleFactory {
+
+    @Override
+    public Module createModule(final String instanceName, final DependencyResolver dependencyResolver,
+        final BundleContext bundleContext) {
+        final Stateful07TopologySessionListenerModule module = (Stateful07TopologySessionListenerModule)
+            super.createModule(instanceName, dependencyResolver, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
 
+    @Override
+    public Module createModule(final String instanceName, final DependencyResolver dependencyResolver,
+        final DynamicMBeanWithInstance old, final BundleContext bundleContext) throws Exception {
+        final Stateful07TopologySessionListenerModule module = (Stateful07TopologySessionListenerModule)
+            super.createModule(instanceName, dependencyResolver, old, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
 }
diff --git a/pcep/topology-provider/src/main/resources/org/opendaylight/blueprint/pcep-topology.xml b/pcep/topology-provider/src/main/resources/org/opendaylight/blueprint/pcep-topology.xml
new file mode 100644 (file)
index 0000000..8d80176
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+           xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0">
+
+    <bean id="Stateful07TopologySessionListenerFactory"
+          class="org.opendaylight.bgpcep.pcep.topology.provider.Stateful07TopologySessionListenerFactory"/>
+    <service ref="Stateful07TopologySessionListenerFactory"
+             interface="org.opendaylight.bgpcep.pcep.topology.provider.TopologySessionListenerFactory">
+        <!-- The following service properties specify the config system module and instance that correspond to
+             this OSGi service which enables the config system module to be restarted when this blueprint
+             container is restarted. -->
+        <service-properties>
+            <entry key="config-module-namespace" value="urn:opendaylight:params:xml:ns:yang:controller:pcep:topology:provider"/>
+            <entry key="config-module-name" value="pcep-topology-stateful07"/>
+            <entry key="config-instance-name" value="global"/>
+        </service-properties>
+    </service>
+
+    <reference id="dataBroker" interface="org.opendaylight.controller.md.sal.binding.api.DataBroker" odl:type="pingpong"/>
+    <reference id="rpcRegistry" interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry"/>
+    <reference id="pcepDispatcher" interface="org.opendaylight.protocol.pcep.PCEPDispatcher"/>
+
+    <bean id="pcepTopologyDeployer" class="org.opendaylight.bgpcep.pcep.topology.provider.config.PCEPTopologyDeployerImpl"
+          destroy-method="close">
+        <argument ref="blueprintContainer"/>
+    </bean>
+    <service ref="pcepTopologyDeployer" interface="org.opendaylight.bgpcep.pcep.topology.provider.config.PCEPTopologyDeployer"/>
+
+    <bean id="PCEPTopologyProviderBean" class="org.opendaylight.bgpcep.pcep.topology.provider.config.PCEPTopologyProviderBean"
+          scope="prototype">
+        <argument ref="blueprintBundleContext"/>
+        <argument ref="dataBroker"/>
+        <argument ref="pcepDispatcher"/>
+        <argument ref="rpcRegistry"/>
+        <argument ref="Stateful07TopologySessionListenerFactory"/>
+    </bean>
+</blueprint>
\ No newline at end of file
index f37a0fdfa026b8780dd1ae587265b92229bb601b..a6b025ccfed26c9e31ba100e99851cd55c61b94a 100644 (file)
@@ -145,7 +145,7 @@ public abstract class AbstractPCEPSessionTest<T extends TopologySessionListenerF
 
         this.listenerFactory = (T) ((Class) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]).newInstance();
         this.manager = new ServerSessionManager(getDataBroker(), TOPO_IID, this.listenerFactory, RPC_TIMEOUT);
-        this.manager.setRuntimeRootRegistartion(registrator);
+        this.manager.setRuntimeRootRegistrator(registrator);
 
         this.neg = new DefaultPCEPSessionNegotiator(mock(Promise.class), this.clientListener, this.manager.getSessionListener(), (short) 1, 5, this.localPrefs);
         this.topologyRpcs = new TopologyRPCs(this.manager);