2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.bgpcep.pcep.topology.provider;
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static java.util.Objects.requireNonNull;
13 import com.google.common.base.Optional;
14 import com.google.common.util.concurrent.ListenableFuture;
15 import io.netty.channel.Channel;
16 import io.netty.channel.ChannelFuture;
17 import io.netty.channel.ChannelFutureListener;
18 import java.net.InetSocketAddress;
19 import java.util.List;
20 import org.opendaylight.bgpcep.pcep.topology.provider.config.PCEPTopologyConfigDependencies;
21 import org.opendaylight.bgpcep.pcep.topology.provider.config.PCEPTopologyProviderDependenciesProvider;
22 import org.opendaylight.bgpcep.programming.spi.InstructionScheduler;
23 import org.opendaylight.bgpcep.topology.DefaultTopologyReference;
24 import org.opendaylight.controller.config.yang.pcep.topology.provider.PCEPTopologyProviderRuntimeRegistrator;
25 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
26 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
27 import org.opendaylight.protocol.concepts.KeyMapping;
28 import org.opendaylight.protocol.pcep.PCEPCapability;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.topology.rev140113.NetworkTopologyContext;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.programming.rev131106.NetworkTopologyPcepProgrammingService;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.NetworkTopologyPcepService;
32 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
33 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
34 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
35 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
39 public final class PCEPTopologyProvider extends DefaultTopologyReference {
40 private static final Logger LOG = LoggerFactory.getLogger(PCEPTopologyProvider.class);
42 private static final String STATEFUL_NOT_DEFINED = "Stateful capability not defined, aborting PCEP Topology" +
43 " Provider instantiation";
44 private final InstanceIdentifier<Topology> topology;
45 private final ServerSessionManager manager;
46 private final InetSocketAddress address;
47 private final KeyMapping keys;
48 private final InstructionScheduler scheduler;
49 private final PCEPTopologyProviderDependenciesProvider dependenciesProvider;
50 private RoutedRpcRegistration<NetworkTopologyPcepProgrammingService> network;
51 private RoutedRpcRegistration<NetworkTopologyPcepService> element;
52 private Channel channel;
54 public static PCEPTopologyProvider create(final PCEPTopologyProviderDependenciesProvider dependenciesProvider,
55 final PCEPTopologyConfigDependencies configDependencies) {
56 final List<PCEPCapability> capabilities = dependenciesProvider.getPCEPDispatcher()
57 .getPCEPSessionNegotiatorFactory().getPCEPSessionProposalFactory().getCapabilities();
58 boolean statefulCapability = false;
59 for (final PCEPCapability capability : capabilities) {
60 if (capability.isStateful()) {
61 statefulCapability = true;
66 final TopologySessionListenerFactory listenerFactory = dependenciesProvider.getTopologySessionListenerFactory();
67 if (!statefulCapability && listenerFactory != null) {
68 throw new IllegalStateException(STATEFUL_NOT_DEFINED);
71 final InstanceIdentifier<Topology> topology = InstanceIdentifier.builder(NetworkTopology.class)
72 .child(Topology.class, new TopologyKey(configDependencies.getTopologyId())).build();
73 final ServerSessionManager manager = new ServerSessionManager(dependenciesProvider.getDataBroker(), topology,
74 listenerFactory, configDependencies.getRpcTimeout());
75 final Optional<PCEPTopologyProviderRuntimeRegistrator> runtime = configDependencies.getRuntimeRootRegistrator();
76 if(runtime.isPresent()){
77 manager.setRuntimeRootRegistrator(runtime.get());
80 return new PCEPTopologyProvider(configDependencies.getAddress(), configDependencies.getKeys(),
81 dependenciesProvider, topology, manager, configDependencies.getSchedulerDependency());
84 private PCEPTopologyProvider(final InetSocketAddress address, final KeyMapping keys,
85 final PCEPTopologyProviderDependenciesProvider dependenciesProvider,
86 final InstanceIdentifier<Topology> topology, final ServerSessionManager manager,
87 final InstructionScheduler scheduler) {
89 this.dependenciesProvider = requireNonNull(dependenciesProvider);
90 this.address = address;
91 this.topology = requireNonNull(topology);
93 this.manager = requireNonNull(manager);
94 this.scheduler = scheduler;
97 public void instantiateServiceInstance() {
98 final RpcProviderRegistry rpcRegistry = this.dependenciesProvider.getRpcProviderRegistry();
100 this.element = requireNonNull(rpcRegistry
101 .addRoutedRpcImplementation(NetworkTopologyPcepService.class, new TopologyRPCs(this.manager)));
102 this.element.registerPath(NetworkTopologyContext.class, this.topology);
104 this.network = requireNonNull(rpcRegistry
105 .addRoutedRpcImplementation(NetworkTopologyPcepProgrammingService.class,
106 new TopologyProgramming(this.scheduler, this.manager)));
107 this.network.registerPath(NetworkTopologyContext.class, this.topology);
109 this.manager.instantiateServiceInstance().get();
110 final ChannelFuture channelFuture = this.dependenciesProvider.getPCEPDispatcher()
111 .createServer(this.address, this.keys, this.manager, this.manager);
113 this.channel = channelFuture.channel();
114 } catch (final Exception e) {
115 LOG.error("Failed to instantiate PCEP Topology provider", e);
120 public ListenableFuture<Void> closeServiceInstance() {
121 //FIXME return also channelClose once ListenableFuture implements wildcard
122 this.channel.close().addListener((ChannelFutureListener) future ->
123 checkArgument(future.isSuccess(), "Channel failed to close: %s", future.cause()));
125 if (this.network != null) {
126 this.network.close();
129 if (this.element != null) {
130 this.element.close();
133 return this.manager.closeServiceInstance();