import io.netty.channel.ChannelFuture;
import java.net.InetSocketAddress;
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.jdt.annotation.NonNullByDefault;
import org.opendaylight.protocol.concepts.KeyMapping;
/**
* Dispatcher class for creating servers and clients.
*/
+@NonNullByDefault
public interface PCEPDispatcher {
/**
* Creates server. Each server needs three factories to pass their instances to client sessions.
* @param tcpKeys RFC2385 TCP-MD5 keys
* @param registry a message registry
* @param negotiatorFactory a negotiation factory
- * @param listenerFactory {@link PCEPSessionListenerFactory} to create listeners for clients
- * @param peerProposal optional information used in our Open message
* @return A future completing when the PCEP server is created
*/
- @NonNull ChannelFuture createServer(@NonNull InetSocketAddress listenAddress, @NonNull KeyMapping tcpKeys,
- @NonNull MessageRegistry registry, @NonNull PCEPSessionNegotiatorFactory negotiatorFactory,
- @NonNull PCEPSessionListenerFactory listenerFactory, @Nullable PCEPPeerProposal peerProposal);
+ ChannelFuture createServer(InetSocketAddress listenAddress, KeyMapping tcpKeys, MessageRegistry registry,
+ PCEPSessionNegotiatorFactory negotiatorFactory);
}
import io.netty.channel.Channel;
import io.netty.util.concurrent.Promise;
import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
/**
* Factory for creating PCEP session negotiator.
* @param promise session promise
* @return PCEPSessionNegotiator instance
*/
- @NonNull SessionNegotiator getSessionNegotiator(@NonNull Channel channel, @NonNull Promise<PCEPSession> promise,
- @NonNull PCEPSessionListenerFactory listenerFactory, @Nullable PCEPPeerProposal peerProposal);
+ @NonNull SessionNegotiator getSessionNegotiator(@NonNull Channel channel, @NonNull Promise<PCEPSession> promise);
}
*/
package org.opendaylight.protocol.pcep.impl;
-import static java.util.Objects.requireNonNull;
-
import com.google.common.primitives.UnsignedBytes;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import java.net.InetSocketAddress;
import java.util.Comparator;
import java.util.concurrent.ExecutionException;
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.protocol.pcep.PCEPPeerProposal;
import org.opendaylight.protocol.pcep.PCEPSession;
-import org.opendaylight.protocol.pcep.PCEPSessionListenerFactory;
import org.opendaylight.protocol.pcep.PCEPSessionNegotiatorFactory;
import org.opendaylight.protocol.pcep.SessionNegotiator;
import org.opendaylight.protocol.pcep.impl.PCEPPeerRegistry.SessionReference;
* @param promise Session promise to be completed by the negotiator
* @param channel Associated channel
* @param sessionId Session ID assigned to the resulting session
- * @param listenerFactory {@link PCEPSessionListenerFactory} to create listeners for clients
- * @param peerProposal optional information used in our Open message
* @return a PCEP session negotiator
*/
protected abstract AbstractPCEPSessionNegotiator createNegotiator(Promise<PCEPSession> promise, Channel channel,
- Uint8 sessionId, PCEPSessionListenerFactory listenerFactory, @Nullable PCEPPeerProposal peerProposal);
+ Uint8 sessionId);
@Override
- public final SessionNegotiator getSessionNegotiator(final Channel channel, final Promise<PCEPSession> promise,
- final PCEPSessionListenerFactory listenerFactory, final PCEPPeerProposal peerProposal) {
+ public final SessionNegotiator getSessionNegotiator(final Channel channel, final Promise<PCEPSession> promise) {
LOG.debug("Instantiating bootstrap negotiator for channel {}", channel);
- return new BootstrapSessionNegotiator(channel, promise, listenerFactory, peerProposal);
+ return new BootstrapSessionNegotiator(channel, promise);
}
private final class BootstrapSessionNegotiator extends AbstractSessionNegotiator {
private static final Comparator<byte[]> COMPARATOR = UnsignedBytes.lexicographicalComparator();
- private final @NonNull PCEPSessionListenerFactory listenerFactory;
- private final @Nullable PCEPPeerProposal peerProposal;
-
- BootstrapSessionNegotiator(final Channel channel, final Promise<PCEPSession> promise,
- final PCEPSessionListenerFactory listenerFactory, final @Nullable PCEPPeerProposal peerProposal) {
+ BootstrapSessionNegotiator(final Channel channel, final Promise<PCEPSession> promise) {
super(promise, channel);
- this.listenerFactory = requireNonNull(listenerFactory);
- this.peerProposal = peerProposal;
}
@Override
}
final Uint8 sessionId = sessionRegistry.nextSession(clientAddress);
- final var negotiator = createNegotiator(promise, channel, sessionId, listenerFactory, peerProposal);
+ final var negotiator = createNegotiator(promise, channel, sessionId);
sessionRegistry.putSessionReference(clientAddress, new SessionReference() {
@Override
import java.util.List;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.protocol.pcep.PCEPCapability;
-import org.opendaylight.protocol.pcep.PCEPPeerProposal;
import org.opendaylight.protocol.pcep.PCEPSession;
import org.opendaylight.protocol.pcep.PCEPSessionListenerFactory;
import org.opendaylight.protocol.pcep.PCEPTimerProposal;
import org.opendaylight.yangtools.yang.common.Uint16;
import org.opendaylight.yangtools.yang.common.Uint8;
-public final class DefaultPCEPSessionNegotiatorFactory extends AbstractPCEPSessionNegotiatorFactory {
+public class DefaultPCEPSessionNegotiatorFactory extends AbstractPCEPSessionNegotiatorFactory {
+ private final @NonNull PCEPSessionListenerFactory listenerFactory;
private final @NonNull PCEPTimerProposal timers;
private final @NonNull List<PCEPCapability> capabilities;
private final @NonNull Uint16 maxUnknownMessages;
private final PcepSessionTls tlsConfiguration;
- public DefaultPCEPSessionNegotiatorFactory(final PcepSessionTimers timers, final List<PCEPCapability> capabilities,
- final Uint16 maxUnknownMessages) {
- this(timers, capabilities, maxUnknownMessages, null);
+ public DefaultPCEPSessionNegotiatorFactory(final PCEPSessionListenerFactory listenerFactory,
+ final PcepSessionTimers timers, final List<PCEPCapability> capabilities, final Uint16 maxUnknownMessages) {
+ this(listenerFactory, timers, capabilities, maxUnknownMessages, null);
}
- public DefaultPCEPSessionNegotiatorFactory(final PcepSessionTimers timers, final List<PCEPCapability> capabilities,
- final Uint16 maxUnknownMessages, final PcepSessionTls tlsConfiguration) {
- this(new PCEPTimerProposal(timers), capabilities, maxUnknownMessages, tlsConfiguration);
+ public DefaultPCEPSessionNegotiatorFactory(final PCEPSessionListenerFactory listenerFactory,
+ final PcepSessionTimers timers, final List<PCEPCapability> capabilities, final Uint16 maxUnknownMessages,
+ final PcepSessionTls tlsConfiguration) {
+ this(listenerFactory, new PCEPTimerProposal(timers), capabilities, maxUnknownMessages, tlsConfiguration);
}
- public DefaultPCEPSessionNegotiatorFactory(final PCEPTimerProposal timers, final List<PCEPCapability> capabilities,
- final Uint16 maxUnknownMessages, final PcepSessionTls tlsConfiguration) {
+ public DefaultPCEPSessionNegotiatorFactory(final PCEPSessionListenerFactory listenerFactory,
+ final PCEPTimerProposal timers, final List<PCEPCapability> capabilities, final Uint16 maxUnknownMessages,
+ final PcepSessionTls tlsConfiguration) {
+ this.listenerFactory = requireNonNull(listenerFactory);
this.timers = requireNonNull(timers);
this.capabilities = requireNonNull(capabilities);
this.maxUnknownMessages = requireNonNull(maxUnknownMessages);
}
@Override
- protected AbstractPCEPSessionNegotiator createNegotiator(final Promise<PCEPSession> promise, final Channel channel,
- final Uint8 sessionId, final PCEPSessionListenerFactory listenerFactory,
- final PCEPPeerProposal peerProposal) {
+ protected final AbstractPCEPSessionNegotiator createNegotiator(final Promise<PCEPSession> promise,
+ final Channel channel, final Uint8 sessionId) {
final var address = (InetSocketAddress) channel.remoteAddress();
final var builder = new TlvsBuilder();
capability.setCapabilityProposal(address, builder);
}
- if (peerProposal != null) {
- peerProposal.setPeerSpecificProposal(address, builder);
- }
+ appendPeerSpecificTls(address, builder);
return new DefaultPCEPSessionNegotiator(promise, channel, listenerFactory.getSessionListener(), sessionId,
new OpenBuilder()
.setTlvs(builder.build())
.build(), maxUnknownMessages, tlsConfiguration);
}
+
+ protected void appendPeerSpecificTls(final @NonNull InetSocketAddress address, final @NonNull TlvsBuilder builder) {
+ // No-op by default
+ }
}
import org.opendaylight.protocol.concepts.KeyMapping;
import org.opendaylight.protocol.pcep.MessageRegistry;
import org.opendaylight.protocol.pcep.PCEPDispatcher;
-import org.opendaylight.protocol.pcep.PCEPPeerProposal;
import org.opendaylight.protocol.pcep.PCEPSession;
-import org.opendaylight.protocol.pcep.PCEPSessionListenerFactory;
import org.opendaylight.protocol.pcep.PCEPSessionNegotiatorFactory;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
@Override
public final synchronized ChannelFuture createServer(final InetSocketAddress listenAddress,
final KeyMapping tcpKeys, final MessageRegistry registry,
- final PCEPSessionNegotiatorFactory negotiatorFactory, final PCEPSessionListenerFactory listenerFactory,
- final PCEPPeerProposal peerProposal) {
+ final PCEPSessionNegotiatorFactory negotiatorFactory) {
final var hf = new PCEPHandlerFactory(registry);
final ChannelPipelineInitializer initializer = (ch, promise) -> {
ch.pipeline().addLast(hf.getDecoders());
- ch.pipeline().addLast("negotiator",
- negotiatorFactory.getSessionNegotiator(ch, promise, listenerFactory, peerProposal));
+ ch.pipeline().addLast("negotiator", negotiatorFactory.getSessionNegotiator(ch, promise));
ch.pipeline().addLast(hf.getEncoders());
};
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.same;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
+import org.eclipse.jdt.annotation.NonNull;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.protocol.concepts.KeyMapping;
import org.opendaylight.protocol.pcep.MessageRegistry;
import org.opendaylight.protocol.pcep.PCEPSession;
-import org.opendaylight.protocol.pcep.PCEPSessionListenerFactory;
import org.opendaylight.protocol.pcep.PCEPSessionNegotiatorFactory;
import org.opendaylight.protocol.pcep.PCEPTimerProposal;
import org.opendaylight.protocol.pcep.spi.pojo.DefaultPCEPExtensionConsumerContext;
@RunWith(MockitoJUnitRunner.StrictStubs.class)
public class PCEPDispatcherImplTest {
- private static final Uint8 DEAD_TIMER = Uint8.valueOf(120);
- private static final Uint8 KEEP_ALIVE = Uint8.valueOf(30);
+ private static final @NonNull Uint8 DEAD_TIMER = Uint8.valueOf(120);
+ private static final @NonNull Uint8 KEEP_ALIVE = Uint8.valueOf(30);
private static final int RETRY_TIMER = 0;
private static final int CONNECT_TIMEOUT = 500;
@Mock
private Channel mockChannel;
- @Mock
- private PCEPSessionListenerFactory listenerFactory;
private MessageRegistry msgReg;
private PCEPSessionNegotiatorFactory negotiatorFactory;
public void setUp() {
msgReg = new DefaultPCEPExtensionConsumerContext().getMessageHandlerRegistry();
- negotiatorFactory = new DefaultPCEPSessionNegotiatorFactory(new PCEPTimerProposal(KEEP_ALIVE, DEAD_TIMER),
- List.of(), Uint16.ZERO, null);
+ negotiatorFactory = new DefaultPCEPSessionNegotiatorFactory(SimpleSessionListener::new,
+ new PCEPTimerProposal(KEEP_ALIVE, DEAD_TIMER), List.of(), Uint16.ZERO, null);
dispatcher = new PCEPDispatcherImpl();
final InetSocketAddress clientAddr1 = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port);
final InetSocketAddress clientAddr2 = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port);
- doReturn(new SimpleSessionListener()).when(listenerFactory).getSessionListener();
final ChannelFuture futureChannel = dispatcher.createServer(serverAddr, KeyMapping.of(), msgReg,
- negotiatorFactory, listenerFactory, null);
+ negotiatorFactory);
futureChannel.sync();
- try (var session1 = (PCEPSessionImpl) pccMock.createClient(clientAddr1,
- RETRY_TIMER, CONNECT_TIMEOUT, SimpleSessionListener::new).get()) {
-
- try (var session2 = (PCEPSessionImpl) pccMock.createClient(clientAddr2,
- RETRY_TIMER, CONNECT_TIMEOUT, SimpleSessionListener::new).get()) {
+ try (var session1 = (PCEPSessionImpl) pccMock.createClient(clientAddr1, RETRY_TIMER, CONNECT_TIMEOUT).get()) {
+ try (var session2 = (PCEPSessionImpl) pccMock.createClient(clientAddr2, RETRY_TIMER, CONNECT_TIMEOUT)
+ .get()) {
assertTrue(futureChannel.channel().isActive());
assertEquals(clientAddr1.getAddress().getHostAddress(), session1.getPeerPref().getIpAddress());
final InetSocketAddress serverAddr = new InetSocketAddress("0.0.0.0", port);
final InetSocketAddress clientAddr = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port);
- doReturn(new SimpleSessionListener()).when(listenerFactory).getSessionListener();
-
- dispatcher.createServer(serverAddr, KeyMapping.of(), msgReg, negotiatorFactory, listenerFactory, null)
- .sync();
- final Future<PCEPSession> futureClient = pccMock.createClient(clientAddr, RETRY_TIMER, CONNECT_TIMEOUT,
- SimpleSessionListener::new);
+ dispatcher.createServer(serverAddr, KeyMapping.of(), msgReg, negotiatorFactory).sync();
+ final Future<PCEPSession> futureClient = pccMock.createClient(clientAddr, RETRY_TIMER, CONNECT_TIMEOUT);
futureClient.sync();
try (PCEPSession ignored = futureClient.get()) {
final var cause = assertThrows(ExecutionException.class,
- () -> pccMock.createClient(clientAddr, RETRY_TIMER, CONNECT_TIMEOUT, SimpleSessionListener::new).get())
+ () -> pccMock.createClient(clientAddr, RETRY_TIMER, CONNECT_TIMEOUT).get())
.getCause();
assertThat(cause, instanceOf(IllegalStateException.class));
assertThat(cause.getMessage(), allOf(
final int port = InetSocketAddressUtil.getRandomPort();
final InetSocketAddress clientAddr = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port);
- doReturn(new SimpleSessionListener()).when(listenerFactory).getSessionListener();
- dispatcher.createServer(new InetSocketAddress("0.0.0.0", port), KeyMapping.of(), msgReg, negotiatorFactory,
- listenerFactory, null).sync();
+ dispatcher.createServer(new InetSocketAddress("0.0.0.0", port), KeyMapping.of(), msgReg, negotiatorFactory)
+ .sync();
final PCEPSessionImpl session1 = (PCEPSessionImpl) pccMock.createClient(clientAddr,
- RETRY_TIMER, CONNECT_TIMEOUT, SimpleSessionListener::new).get();
+ RETRY_TIMER, CONNECT_TIMEOUT).get();
assertEquals(clientAddr.getAddress(), session1.getRemoteAddress());
assertEquals(DEAD_TIMER.toJava(), session1.getDeadTimerValue());
assertEquals(KEEP_ALIVE.toJava(), session1.getKeepAliveTimerValue());
session1.closeChannel().sync();
- try (var session2 = (PCEPSessionImpl) pccMock.createClient(clientAddr, RETRY_TIMER, CONNECT_TIMEOUT,
- SimpleSessionListener::new).get()) {
+ try (var session2 = (PCEPSessionImpl) pccMock.createClient(clientAddr, RETRY_TIMER, CONNECT_TIMEOUT).get()) {
assertEquals(clientAddr.getAddress(), session1.getRemoteAddress());
assertEquals(DEAD_TIMER.toJava(), session2.getDeadTimerValue());
clientAddr1.getAddress(), "CLIENT1_ADDRESS",
clientAddr2.getAddress(), "CLIENT2_ADDRESS"));
- final ChannelFuture futureChannel = disp2Spy.createServer(new InetSocketAddress("0.0.0.0", port),
- keys, msgReg, negotiatorFactory, null, null).sync();
+ final ChannelFuture futureChannel = disp2Spy.createServer(new InetSocketAddress("0.0.0.0", port), keys, msgReg,
+ negotiatorFactory).sync();
verify(disp2Spy).createServerBootstrap(any(PCEPDispatcherImpl.ChannelPipelineInitializer.class), same(keys));
}
}
Future<PCEPSession> createClient(final InetSocketAddress address, final int retryTimer,
- final int connectTimeout, final PCEPSessionListenerFactory listenerFactory) {
+ final int connectTimeout) {
return createClient(address, retryTimer, connectTimeout, (ch, promise) -> {
ch.pipeline().addLast(factory.getDecoders());
- ch.pipeline().addLast("negotiator", negotiatorFactory.getSessionNegotiator(ch, promise, listenerFactory,
- null));
+ ch.pipeline().addLast("negotiator", negotiatorFactory.getSessionNegotiator(ch, promise));
ch.pipeline().addLast(factory.getEncoders());
});
}
--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech, 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.protocol.pcep.pcc.mock;
+
+import java.net.InetSocketAddress;
+import java.util.List;
+import org.opendaylight.protocol.pcep.PCEPCapability;
+import org.opendaylight.protocol.pcep.PCEPPeerProposal;
+import org.opendaylight.protocol.pcep.PCEPSessionListenerFactory;
+import org.opendaylight.protocol.pcep.PCEPTimerProposal;
+import org.opendaylight.protocol.pcep.impl.DefaultPCEPSessionNegotiatorFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.config.rev230112.PcepSessionTls;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.open.object.open.TlvsBuilder;
+import org.opendaylight.yangtools.yang.common.Uint16;
+
+final class CustomPCEPSessionNegotiatorFactory extends DefaultPCEPSessionNegotiatorFactory {
+ private final PCEPPeerProposal peerProposal;
+
+ CustomPCEPSessionNegotiatorFactory(final PCEPSessionListenerFactory listenerFactory,
+ final PCEPTimerProposal timers, final List<PCEPCapability> capabilities,
+ final Uint16 maxUnknownMessages, final PcepSessionTls tlsConfiguration,
+ final PCEPPeerProposal peerProposal) {
+ super(listenerFactory, timers, capabilities, maxUnknownMessages, tlsConfiguration);
+ this.peerProposal = peerProposal;
+ }
+
+ @Override
+ protected void appendPeerSpecificTls(final InetSocketAddress address, final TlvsBuilder builder) {
+ if (peerProposal != null) {
+ peerProposal.setPeerSpecificProposal(address, builder);
+ }
+ }
+}
\ No newline at end of file
*/
package org.opendaylight.protocol.pcep.pcc.mock;
-import static java.util.Objects.requireNonNull;
-
import com.google.common.net.InetAddresses;
import io.netty.util.HashedWheelTimer;
import io.netty.util.Timer;
import org.opendaylight.protocol.concepts.KeyMapping;
import org.opendaylight.protocol.pcep.MessageRegistry;
import org.opendaylight.protocol.pcep.PCEPCapability;
-import org.opendaylight.protocol.pcep.PCEPSessionNegotiatorFactory;
import org.opendaylight.protocol.pcep.PCEPTimerProposal;
-import org.opendaylight.protocol.pcep.impl.DefaultPCEPSessionNegotiatorFactory;
import org.opendaylight.protocol.pcep.pcc.mock.api.PCCTunnelManager;
import org.opendaylight.protocol.pcep.pcc.mock.protocol.PCCDispatcherImpl;
+import org.opendaylight.protocol.pcep.pcc.mock.protocol.PCCPeerProposal;
import org.opendaylight.protocol.pcep.pcc.mock.protocol.PCCSessionListener;
import org.opendaylight.protocol.pcep.spi.pojo.DefaultPCEPExtensionConsumerContext;
import org.opendaylight.yangtools.yang.common.Uint16;
private final int pccCount;
private final InetSocketAddress localAddress;
private final List<InetSocketAddress> remoteAddress;
- private final Uint8 keepAlive;
- private final Uint8 deadTimer;
+ private final PCEPTimerProposal timers;
private final String password;
private final long reconnectTime;
private final int redelegationTimeout;
this.pccCount = pccCount;
this.localAddress = localAddress;
this.remoteAddress = remoteAddress;
- this.keepAlive = requireNonNull(keepAlive);
- this.deadTimer = requireNonNull(deadTimer);
this.password = password;
this.reconnectTime = reconnectTime;
this.redelegationTimeout = redelegationTimeout;
this.stateTimeout = stateTimeout;
this.pcepCapabilities = pcepCapabilities;
-
+ timers = new PCEPTimerProposal(keepAlive, deadTimer);
registry = new DefaultPCEPExtensionConsumerContext().getMessageHandlerRegistry();
}
private void createPCC(final PCCDispatcherImpl pccDispatcher, final @NonNull InetSocketAddress plocalAddress,
final PCCTunnelManager tunnelManager, final Uint64 initialDBVersion) {
- final PCEPSessionNegotiatorFactory snf = getSessionNegotiatorFactory();
for (final InetSocketAddress pceAddress : remoteAddress) {
- pccDispatcher.createClient(pceAddress, reconnectTime,
- () -> new PCCSessionListener(remoteAddress.indexOf(pceAddress), tunnelManager, pcError), snf,
- password == null ? KeyMapping.of() : KeyMapping.of(pceAddress.getAddress(), password),
- plocalAddress, initialDBVersion);
+ pccDispatcher.createClient(pceAddress, reconnectTime, new CustomPCEPSessionNegotiatorFactory(
+ () -> new PCCSessionListener(remoteAddress.indexOf(pceAddress), tunnelManager, pcError),
+ timers, List.of(pcepCapabilities), Uint16.ZERO, null, new PCCPeerProposal(initialDBVersion)),
+ password == null ? KeyMapping.of() : KeyMapping.of(pceAddress.getAddress(), password),
+ plocalAddress);
}
}
-
- private PCEPSessionNegotiatorFactory getSessionNegotiatorFactory() {
- return new DefaultPCEPSessionNegotiatorFactory(new PCEPTimerProposal(keepAlive, deadTimer),
- List.of(pcepCapabilities), Uint16.ZERO, null);
- }
}
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.protocol.concepts.KeyMapping;
import org.opendaylight.protocol.pcep.PCEPSession;
-import org.opendaylight.protocol.pcep.PCEPSessionListenerFactory;
import org.opendaylight.protocol.pcep.PCEPSessionNegotiatorFactory;
-import org.opendaylight.yangtools.yang.common.Uint64;
public interface PCCDispatcher {
- @NonNull Future<PCEPSession> createClient(@NonNull InetSocketAddress remoteAddress,
- long reconnectTime, @NonNull PCEPSessionListenerFactory listenerFactory,
- @NonNull PCEPSessionNegotiatorFactory negotiatorFactory, @NonNull KeyMapping keys,
- @NonNull InetSocketAddress localAddress, @NonNull Uint64 dbVersion);
-
- @NonNull Future<PCEPSession> createClient(@NonNull InetSocketAddress remoteAddress,
- long reconnectTime, @NonNull PCEPSessionListenerFactory listenerFactory,
- @NonNull PCEPSessionNegotiatorFactory negotiatorFactory, @NonNull KeyMapping keys,
- @NonNull InetSocketAddress localAddress);
+ @NonNull Future<PCEPSession> createClient(@NonNull InetSocketAddress remoteAddress, long reconnectTime,
+ @NonNull PCEPSessionNegotiatorFactory negotiatorFactory, @NonNull KeyMapping keys,
+ @NonNull InetSocketAddress localAddress);
}
import org.opendaylight.protocol.concepts.KeyMapping;
import org.opendaylight.protocol.pcep.MessageRegistry;
import org.opendaylight.protocol.pcep.PCEPSession;
-import org.opendaylight.protocol.pcep.PCEPSessionListenerFactory;
import org.opendaylight.protocol.pcep.PCEPSessionNegotiatorFactory;
import org.opendaylight.protocol.pcep.impl.PCEPHandlerFactory;
import org.opendaylight.protocol.pcep.pcc.mock.api.PCCDispatcher;
-import org.opendaylight.yangtools.yang.common.Uint64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Override
public Future<PCEPSession> createClient(final InetSocketAddress remoteAddress, final long reconnectTime,
- final PCEPSessionListenerFactory listenerFactory, final PCEPSessionNegotiatorFactory negotiatorFactory,
- final KeyMapping keys, final InetSocketAddress localAddress) {
- return createClient(remoteAddress, reconnectTime, listenerFactory, negotiatorFactory, keys, localAddress,
- Uint64.ONE);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public Future<PCEPSession> createClient(final InetSocketAddress remoteAddress, final long reconnectTime,
- final PCEPSessionListenerFactory listenerFactory, final PCEPSessionNegotiatorFactory negotiatorFactory,
- final KeyMapping keys, final InetSocketAddress localAddress, final Uint64 dbVersion) {
+ final PCEPSessionNegotiatorFactory negotiatorFactory, final KeyMapping keys,
+ final InetSocketAddress localAddress) {
final Bootstrap b = new Bootstrap();
b.group(workerGroup);
b.localAddress(localAddress);
@Override
protected void initChannel(final SocketChannel ch) {
ch.pipeline().addLast(factory.getDecoders());
- ch.pipeline().addLast("negotiator", negotiatorFactory.getSessionNegotiator(ch, promise, listenerFactory,
- new PCCPeerProposal(dbVersion)));
+ ch.pipeline().addLast("negotiator", negotiatorFactory.getSessionNegotiator(ch, promise));
ch.pipeline().addLast(factory.getEncoders());
ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
@Override
return;
}
LOG.debug("Reconnecting after connection to {} was dropped", remoteAddress);
- PCCDispatcherImpl.this.createClient(
- remoteAddress,
- reconnectTime,
- listenerFactory,
- negotiatorFactory,
- keys,
- localAddress,
- dbVersion);
+ createClient(remoteAddress, reconnectTime, negotiatorFactory, keys, localAddress);
}
});
}
@RunWith(MockitoJUnitRunner.StrictStubs.class)
public class PCCDispatcherImplTest {
- private final DefaultPCEPSessionNegotiatorFactory nf = new DefaultPCEPSessionNegotiatorFactory(
- new PCEPTimerProposal(Uint8.TEN, Uint8.valueOf(40)), List.of(), Uint16.ZERO, null);
-
private PCCDispatcherImpl dispatcher;
private PCEPDispatcherImpl pcepDispatcher;
private InetSocketAddress serverAddress;
@Test(timeout = 20000)
public void testClientReconnect() throws Exception {
- final Future<PCEPSession> futureSession = dispatcher.createClient(serverAddress, 1,
- new TestingSessionListenerFactory(), nf, KeyMapping.of(), clientAddress);
final TestingSessionListenerFactory slf = new TestingSessionListenerFactory();
+ final DefaultPCEPSessionNegotiatorFactory nf = new DefaultPCEPSessionNegotiatorFactory(slf,
+ new PCEPTimerProposal(Uint8.TEN, Uint8.valueOf(40)), List.of(), Uint16.ZERO, null);
+
+ final Future<PCEPSession> futureSession = dispatcher.createClient(serverAddress, 1, nf, KeyMapping.of(),
+ clientAddress);
- final ChannelFuture futureServer = pcepDispatcher.createServer(serverAddress, KeyMapping.of(), registry, nf,
- slf, null);
+ final ChannelFuture futureServer = pcepDispatcher.createServer(serverAddress, KeyMapping.of(), registry, nf);
futureServer.sync();
final Channel channel = futureServer.channel();
assertNotNull(futureSession.get());
pcepDispatcher = new PCEPDispatcherImpl();
final TestingSessionListenerFactory slf2 = new TestingSessionListenerFactory();
- final ChannelFuture future2 = pcepDispatcher.createServer(serverAddress, KeyMapping.of(), registry, nf,
- slf2, null);
+ final ChannelFuture future2 = pcepDispatcher.createServer(serverAddress, KeyMapping.of(), registry,
+ new DefaultPCEPSessionNegotiatorFactory(slf2, new PCEPTimerProposal(Uint8.TEN, Uint8.valueOf(40)),
+ List.of(), Uint16.ZERO, null));
future2.sync();
final Channel channel2 = future2.channel();
final TestingSessionListener sl2 = checkSessionListenerNotNull(slf2,
import org.opendaylight.protocol.pcep.PCEPSessionNegotiatorFactory;
import org.opendaylight.protocol.pcep.PCEPTimerProposal;
import org.opendaylight.protocol.pcep.ietf.stateful.StatefulActivator;
-import org.opendaylight.protocol.pcep.impl.DefaultPCEPSessionNegotiatorFactory;
import org.opendaylight.protocol.pcep.impl.PCEPDispatcherImpl;
import org.opendaylight.protocol.pcep.pcc.mock.api.PCCTunnelManager;
import org.opendaylight.protocol.pcep.pcc.mock.protocol.PCCDispatcherImpl;
+import org.opendaylight.protocol.pcep.pcc.mock.protocol.PCCPeerProposal;
import org.opendaylight.protocol.pcep.pcc.mock.protocol.PCCSessionListener;
import org.opendaylight.protocol.pcep.spi.PCEPExtensionProviderActivator;
import org.opendaylight.protocol.pcep.spi.PCEPExtensionProviderContext;
PCCSessionListener pccSessionListener;
private PCEPDispatcherImpl pceDispatcher;
private final PCEPExtensionProviderContext extensionProvider = new SimplePCEPExtensionProviderContext();
- private PCEPSessionNegotiatorFactory negotiatorFactory;
private MessageRegistry messageRegistry;
protected abstract List<PCEPCapability> getCapabilities();
@Before
public void setUp() {
- negotiatorFactory = getSessionNegotiatorFactory();
-
ServiceLoader.load(PCEPExtensionProviderActivator.class).forEach(act -> act.start(extensionProvider));
-
messageRegistry = extensionProvider.getMessageHandlerRegistry();
pceDispatcher = new PCEPDispatcherImpl();
}
optimizationsActivator.start(extensionProvider);
final ChannelFuture future = pceDispatcher.createServer(serverAddress2, KeyMapping.of(), messageRegistry,
- negotiatorFactory, factory, peerProposal);
+ new CustomPCEPSessionNegotiatorFactory(factory, new PCEPTimerProposal(KEEP_ALIVE, DEAD_TIMER),
+ getCapabilities(), Uint16.ZERO, null, peerProposal));
waitFutureSuccess(future);
return future.channel();
}
Future<PCEPSession> createPCCSession(final Uint64 dbVersion) {
final PCCDispatcherImpl pccDispatcher = new PCCDispatcherImpl(messageRegistry);
- final PCEPSessionNegotiatorFactory snf = getSessionNegotiatorFactory();
final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(3, localAddress.getAddress(),
- 0, -1, new HashedWheelTimer(), Optional.empty());
-
- return pccDispatcher.createClient(remoteAddress, -1, () -> {
+ 0, -1, new HashedWheelTimer(), Optional.empty());
+ final PCEPSessionNegotiatorFactory snf = new CustomPCEPSessionNegotiatorFactory(() -> {
pccSessionListener = new PCCSessionListener(1, tunnelManager, false);
return pccSessionListener;
- }, snf, KeyMapping.of(), localAddress, dbVersion);
- }
+ }, new PCEPTimerProposal(KEEP_ALIVE, DEAD_TIMER), getCapabilities(), Uint16.ZERO, null,
+ new PCCPeerProposal(dbVersion));
- private PCEPSessionNegotiatorFactory getSessionNegotiatorFactory() {
- return new DefaultPCEPSessionNegotiatorFactory(new PCEPTimerProposal(KEEP_ALIVE, DEAD_TIMER),
- getCapabilities(), Uint16.ZERO, null);
+ return pccDispatcher.createClient(remoteAddress, -1, snf, KeyMapping.of(), localAddress);
}
TestingSessionListener getListener(final TestingSessionListenerFactory factory) {
.orElseThrow()
.getMessageHandlerRegistry();
final PCEPDispatcherImpl dispatcher = new PCEPDispatcherImpl();
- dispatcher.createServer(address, KeyMapping.of(), handlerRegistry,
- new DefaultPCEPSessionNegotiatorFactory(new PCEPTimerProposal(keepAliveValue, deadTimerValue),
- List.of(new PCEPStatefulCapability(stateful, active, instant, false, false, false, false)),
- maxUnknownMessages, null), new TestingSessionListenerFactory(), null).get();
+ dispatcher.createServer(address, KeyMapping.of(), handlerRegistry, new DefaultPCEPSessionNegotiatorFactory(
+ new TestingSessionListenerFactory(),
+ new PCEPTimerProposal(keepAliveValue, deadTimerValue),
+ List.of(new PCEPStatefulCapability(stateful, active, instant, false, false, false, false)),
+ maxUnknownMessages, null)).get();
}
}
public static void main(final String[] args) throws InterruptedException, ExecutionException {
checkArgument(args.length > 0, "Host and port of server must be provided.");
- final var snf = new DefaultPCEPSessionNegotiatorFactory(
+ final var snf = new DefaultPCEPSessionNegotiatorFactory(SimpleSessionListener::new,
new PCEPTimerProposal(Uint8.valueOf(30), Uint8.valueOf(120)), List.of(), Uint16.ZERO, null);
final var serverHostAndPort = HostAndPort.fromString(args[0]);
final var serverAddr = new InetSocketAddress(serverHostAndPort.getHost(),
try (var pccDispatcher = new PCCDispatcherImpl(
new DefaultPCEPExtensionConsumerContext().getMessageHandlerRegistry())) {
- pccDispatcher.createClient(serverAddr, -1, SimpleSessionListener::new, snf, KeyMapping.of(), clientAddr)
- .get();
+ pccDispatcher.createClient(serverAddr, -1, snf, KeyMapping.of(), clientAddr).get();
}
}
}
import org.opendaylight.bgpcep.topology.DefaultTopologyReference;
import org.opendaylight.mdsal.binding.api.RpcProviderService;
import org.opendaylight.protocol.pcep.PCEPCapability;
-import org.opendaylight.protocol.pcep.impl.DefaultPCEPSessionNegotiatorFactory;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.programming.rev181109.NetworkTopologyPcepProgrammingService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev220730.NetworkTopologyPcepService;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
@GuardedBy("this")
private ServerSessionManager manager;
@GuardedBy("this")
- private PCEPStatefulPeerProposal proposal;
+ private TopologyPCEPSessionNegotiatorFactory negotiatorFactory;
@GuardedBy("this")
private Channel channel;
@GuardedBy("this")
return;
}
- proposal = new PCEPStatefulPeerProposal(dependencies.getDataBroker(), instanceIdentifier);
+ negotiatorFactory = new TopologyPCEPSessionNegotiatorFactory(manager, currentConfig.getTimerProposal(),
+ dependencies.getCapabilities(), currentConfig.getMaxUnknownMessages(), currentConfig.getTls(),
+ dependencies.getDataBroker(), instanceIdentifier);
LOG.info("PCEP Topology Provider {} starting server channel", topologyId());
final var channelFuture = dependencies.getPCEPDispatcher().createServer(currentConfig.getAddress(),
- currentConfig.getKeys(), dependencies.getMessageRegistry(),
- new DefaultPCEPSessionNegotiatorFactory(currentConfig.getTimerProposal(), dependencies.getCapabilities(),
- currentConfig.getMaxUnknownMessages(), currentConfig.getTls()), manager, proposal);
+ currentConfig.getKeys(), dependencies.getMessageRegistry(), negotiatorFactory);
channelFuture.addListener(ignored -> enableRPCs(future, channelFuture));
}
@Holding("this")
private void disableManager(final SettableFuture<Empty> future) {
- proposal.close();
- proposal = null;
+ negotiatorFactory.close();
+ negotiatorFactory = null;
final var managerStop = manager.stop();
manager = null;
managerStop.addListener(() -> finishStopManager(future), MoreExecutors.directExecutor());
--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech, 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;
+
+import java.net.InetSocketAddress;
+import java.util.List;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.protocol.pcep.PCEPCapability;
+import org.opendaylight.protocol.pcep.PCEPSessionListenerFactory;
+import org.opendaylight.protocol.pcep.PCEPTimerProposal;
+import org.opendaylight.protocol.pcep.impl.DefaultPCEPSessionNegotiatorFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.config.rev230112.PcepSessionTls;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.open.object.open.TlvsBuilder;
+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.KeyedInstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.Uint16;
+
+final class TopologyPCEPSessionNegotiatorFactory extends DefaultPCEPSessionNegotiatorFactory {
+ private final PCEPStatefulPeerProposal proposal;
+
+ TopologyPCEPSessionNegotiatorFactory(final PCEPSessionListenerFactory listenerFactory,
+ final PCEPTimerProposal timers, final List<PCEPCapability> capabilities, final Uint16 maxUnknownMessages,
+ final PcepSessionTls tlsConfiguration, final DataBroker dataBroker,
+ final KeyedInstanceIdentifier<Topology, TopologyKey> topology) {
+ super(listenerFactory, timers, capabilities, maxUnknownMessages, tlsConfiguration);
+ proposal = new PCEPStatefulPeerProposal(dataBroker, topology);
+ }
+
+ @Override
+ protected void appendPeerSpecificTls(final InetSocketAddress address, final TlvsBuilder builder) {
+ proposal.setPeerSpecificProposal(address, builder);
+ }
+
+ void close() {
+ proposal.close();
+ }
+}