Create pcep topology parent aggregator
[bgpcep.git] / pcep / topology / topology-provider / src / main / java / org / opendaylight / bgpcep / pcep / topology / provider / PCEPTopologyProvider.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.bgpcep.pcep.topology.provider;
9
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static java.util.Objects.requireNonNull;
12
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;
38
39 public final class PCEPTopologyProvider extends DefaultTopologyReference {
40     private static final Logger LOG = LoggerFactory.getLogger(PCEPTopologyProvider.class);
41
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;
53
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;
62                 break;
63             }
64         }
65
66         final TopologySessionListenerFactory listenerFactory = dependenciesProvider.getTopologySessionListenerFactory();
67         if (!statefulCapability && listenerFactory != null) {
68             throw new IllegalStateException(STATEFUL_NOT_DEFINED);
69         }
70
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());
78         }
79
80         return new PCEPTopologyProvider(configDependencies.getAddress(), configDependencies.getKeys(),
81             dependenciesProvider, topology, manager,  configDependencies.getSchedulerDependency());
82     }
83
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) {
88         super(topology);
89         this.dependenciesProvider = requireNonNull(dependenciesProvider);
90         this.address = address;
91         this.topology = requireNonNull(topology);
92         this.keys = keys;
93         this.manager = requireNonNull(manager);
94         this.scheduler = scheduler;
95     }
96
97     public void instantiateServiceInstance() {
98         final RpcProviderRegistry rpcRegistry = this.dependenciesProvider.getRpcProviderRegistry();
99
100         this.element = requireNonNull(rpcRegistry
101             .addRoutedRpcImplementation(NetworkTopologyPcepService.class, new TopologyRPCs(this.manager)));
102         this.element.registerPath(NetworkTopologyContext.class, this.topology);
103
104         this.network = requireNonNull(rpcRegistry
105             .addRoutedRpcImplementation(NetworkTopologyPcepProgrammingService.class,
106                 new TopologyProgramming(this.scheduler, this.manager)));
107         this.network.registerPath(NetworkTopologyContext.class, this.topology);
108         try {
109             this.manager.instantiateServiceInstance().get();
110             final ChannelFuture channelFuture = this.dependenciesProvider.getPCEPDispatcher()
111                 .createServer(this.address, this.keys, this.manager, this.manager);
112             channelFuture.get();
113             this.channel = channelFuture.channel();
114         } catch (final Exception e) {
115             LOG.error("Failed to instantiate PCEP Topology provider", e);
116         }
117
118     }
119
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()));
124
125         if (this.network != null) {
126             this.network.close();
127             this.network = null;
128         }
129         if (this.element != null) {
130             this.element.close();
131             this.element = null;
132         }
133         return this.manager.closeServiceInstance();
134     }
135 }