4f00dc805ebdc79100016cba33abe8fba14fc1b1
[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.util.concurrent.FluentFuture;
14 import io.netty.channel.Channel;
15 import io.netty.channel.ChannelFuture;
16 import io.netty.channel.ChannelFutureListener;
17 import java.util.Collections;
18 import java.util.List;
19 import java.util.Optional;
20 import java.util.concurrent.ExecutionException;
21 import org.opendaylight.bgpcep.pcep.topology.provider.config.PCEPTopologyConfiguration;
22 import org.opendaylight.bgpcep.pcep.topology.provider.config.PCEPTopologyProviderDependencies;
23 import org.opendaylight.bgpcep.programming.spi.InstructionScheduler;
24 import org.opendaylight.bgpcep.topology.DefaultTopologyReference;
25 import org.opendaylight.mdsal.binding.api.RpcProviderService;
26 import org.opendaylight.mdsal.common.api.CommitInfo;
27 import org.opendaylight.protocol.pcep.PCEPCapability;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.programming.rev181109.NetworkTopologyPcepProgrammingService;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev181109.NetworkTopologyPcepService;
30 import org.opendaylight.yangtools.concepts.ObjectRegistration;
31
32 public final class PCEPTopologyProvider extends DefaultTopologyReference {
33     private static final String STATEFUL_NOT_DEFINED = "Stateful capability not defined, aborting PCEP Topology"
34             + " Provider instantiation";
35     private final ServerSessionManager manager;
36     private final PCEPTopologyProviderDependencies dependenciesProvider;
37     private final PCEPTopologyConfiguration configDependencies;
38     private final InstructionScheduler scheduler;
39     private ObjectRegistration<NetworkTopologyPcepProgrammingService> network;
40     private ObjectRegistration<NetworkTopologyPcepService> element;
41     private Channel channel;
42
43     private PCEPTopologyProvider(
44             final PCEPTopologyConfiguration configDependencies,
45             final PCEPTopologyProviderDependencies dependenciesProvider,
46             final ServerSessionManager manager, final InstructionScheduler scheduler) {
47         super(configDependencies.getTopology());
48         this.dependenciesProvider = requireNonNull(dependenciesProvider);
49         this.configDependencies = configDependencies;
50         this.manager = requireNonNull(manager);
51         this.scheduler = requireNonNull(scheduler);
52     }
53
54     public static PCEPTopologyProvider create(final PCEPTopologyProviderDependencies dependenciesProvider,
55             final InstructionScheduler scheduler, final PCEPTopologyConfiguration configDependencies) {
56         final List<PCEPCapability> capabilities = dependenciesProvider.getPCEPDispatcher()
57                 .getPCEPSessionNegotiatorFactory().getPCEPSessionProposalFactory().getCapabilities();
58         final Optional<PCEPCapability> statefulCapability = capabilities
59                 .stream()
60                 .filter(PCEPCapability::isStateful)
61                 .findAny();
62
63         final TopologySessionListenerFactory listenerFactory = dependenciesProvider.getTopologySessionListenerFactory();
64         if (!statefulCapability.isPresent()) {
65             throw new IllegalStateException(STATEFUL_NOT_DEFINED);
66         }
67
68         final ServerSessionManager manager = new ServerSessionManager(dependenciesProvider, listenerFactory,
69                 configDependencies);
70
71         return new PCEPTopologyProvider(configDependencies, dependenciesProvider, manager, scheduler);
72     }
73
74     public void instantiateServiceInstance() throws ExecutionException, InterruptedException {
75         final RpcProviderService rpcRegistry = this.dependenciesProvider.getRpcProviderRegistry();
76
77         this.element = requireNonNull(rpcRegistry
78             .registerRpcImplementation(NetworkTopologyPcepService.class, new TopologyRPCs(this.manager),
79                 Collections.singleton(this.configDependencies.getTopology())));
80
81         this.network = requireNonNull(rpcRegistry
82             .registerRpcImplementation(NetworkTopologyPcepProgrammingService.class,
83                 new TopologyProgramming(this.scheduler, this.manager),
84                 Collections.singleton(this.configDependencies.getTopology())));
85
86         this.manager.instantiateServiceInstance();
87         final ChannelFuture channelFuture = this.dependenciesProvider.getPCEPDispatcher()
88                 .createServer(this.manager.getPCEPDispatcherDependencies());
89         channelFuture.get();
90         this.channel = channelFuture.channel();
91     }
92
93     public FluentFuture<? extends CommitInfo> closeServiceInstance() {
94         //FIXME return also channelClose once ListenableFuture implements wildcard
95         this.channel.close().addListener((ChannelFutureListener) future ->
96                 checkArgument(future.isSuccess(), "Channel failed to close: %s", future.cause()));
97
98         if (this.network != null) {
99             this.network.close();
100             this.network = null;
101         }
102         if (this.element != null) {
103             this.element.close();
104             this.element = null;
105         }
106         return this.manager.closeServiceInstance();
107     }
108 }