--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>pcep-pcc-mock</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.m2e.core.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.m2e.core.maven2Nature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright (c) 2014 Cisco Systems, Inc. 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
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.bgpcep</groupId>
+ <artifactId>pcep-parent</artifactId>
+ <version>0.3.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>pcep-pcc-mock</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>pcep-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>pcep-impl</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>concepts</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>protocol-framework</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>pcep-ietf-stateful07</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>pcep-ietf-stateful02</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-common</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-transport</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+
+ <!-- Testing dependencies -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifest>
+ <mainClass>org.opendaylight.protocol.pcep.pcc.mock.Main</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>${maven.shade.version}</version>
+ <configuration>
+ </configuration>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <transformers>
+ <transformer
+ implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+ <mainClass>org.opendaylight.protocol.pcep.pcc.mock.Main</mainClass>
+ </transformer>
+ </transformers>
+ <shadedArtifactAttached>true</shadedArtifactAttached>
+ <shadedClassifierName>executable</shadedClassifierName>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. 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 com.google.common.base.Preconditions;
+import com.google.common.net.InetAddresses;
+import io.netty.util.concurrent.DefaultPromise;
+import io.netty.util.concurrent.GlobalEventExecutor;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.util.concurrent.ExecutionException;
+import org.opendaylight.protocol.framework.NeverReconnectStrategy;
+import org.opendaylight.protocol.framework.SessionListenerFactory;
+import org.opendaylight.protocol.framework.SessionNegotiatorFactory;
+import org.opendaylight.protocol.pcep.PCEPSessionListener;
+import org.opendaylight.protocol.pcep.ietf.stateful07.StatefulActivator;
+import org.opendaylight.protocol.pcep.impl.DefaultPCEPSessionNegotiatorFactory;
+import org.opendaylight.protocol.pcep.impl.PCEPHandlerFactory;
+import org.opendaylight.protocol.pcep.impl.PCEPSessionImpl;
+import org.opendaylight.protocol.pcep.spi.pojo.ServiceLoaderPCEPExtensionProviderContext;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.OpenBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class Main {
+
+ private static final Logger LOG = LoggerFactory.getLogger(Main.class);
+
+ private static final int DEFAULT_PORT = 4189;
+ private static final short DEFAULT_KEEP_ALIVE = 30;
+ private static final short DEFAULT_DEAD_TIMER = 120;
+ private static final int RECONNECT_STRATEGY_TIMEOUT = 2000;
+
+ public static void main(String[] args) throws InterruptedException, ExecutionException, UnknownHostException {
+
+ if (args.length < 2) {
+ LOG.info("Insufficient number of arguments {}.", args.length);
+ return;
+ }
+
+ InetAddress address = null;
+ int pccCount = 1;
+ int lsps = 1;
+ boolean pcError = false;
+
+ int argIdx = 0;
+ while (argIdx < args.length) {
+ if (args[argIdx].equals("--address")) {
+ address = InetAddress.getByName(args[argIdx + 1]);
+ argIdx++;
+ } else if (args[argIdx].equals("--pcc")) {
+ pccCount = Integer.valueOf(args[argIdx + 1]);
+ argIdx++;
+ } else if (args[argIdx].equals("--lsp")) {
+ lsps = Integer.valueOf(args[argIdx + 1]);
+ argIdx++;
+ } else if (args[argIdx].equals("--pcerr")) {
+ pcError = true;
+ argIdx++;
+ } else {
+ LOG.warn("WARNING: Unrecognized argument: {}", args[argIdx]);
+ }
+ argIdx++;
+ }
+ Preconditions.checkState(address != null, "Missing mandatory address parameter.");
+ createPCCs(lsps, pcError, pccCount, address);
+ }
+
+ public static void createPCCs(final int lspsPerPcc, final boolean pcerr, final int pccCount,
+ final InetAddress address) throws InterruptedException, ExecutionException {
+ final SessionNegotiatorFactory<Message, PCEPSessionImpl, PCEPSessionListener> snf = new DefaultPCEPSessionNegotiatorFactory(
+ new OpenBuilder().setKeepalive(DEFAULT_KEEP_ALIVE).setDeadTimer(DEFAULT_DEAD_TIMER).setSessionId((short) 0).build(), 0);
+
+ final StatefulActivator activator07 = new StatefulActivator();
+ final PCCActivator activator = new PCCActivator();
+ activator07.start(ServiceLoaderPCEPExtensionProviderContext.getSingletonInstance());
+ activator.start(ServiceLoaderPCEPExtensionProviderContext.getSingletonInstance());
+ final PCCMock<Message, PCEPSessionImpl, PCEPSessionListener> pcc = new PCCMock<>(snf, new PCEPHandlerFactory(
+ ServiceLoaderPCEPExtensionProviderContext.getSingletonInstance().getMessageHandlerRegistry()),
+ new DefaultPromise<PCEPSessionImpl>(GlobalEventExecutor.INSTANCE));
+
+ InetAddress inetAddress = address;
+ int i = 0;
+ while (i < pccCount) {
+ final int pccNumber = i + 1;
+ final InetAddress pccAddress = inetAddress;
+ pcc.createClient(new InetSocketAddress(pccAddress, DEFAULT_PORT),
+ new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, RECONNECT_STRATEGY_TIMEOUT),
+ new SessionListenerFactory<PCEPSessionListener>() {
+
+ @Override
+ public PCEPSessionListener getSessionListener() {
+ return new SimpleSessionListener(lspsPerPcc, pcerr, pccNumber, pccAddress);
+ }
+ }).get();
+ i++;
+ inetAddress = InetAddresses.increment(inetAddress);
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. 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 com.google.common.base.Charsets;
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+import java.net.InetAddress;
+import java.util.Arrays;
+import java.util.List;
+import org.opendaylight.protocol.pcep.spi.PCEPErrors;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.OperationalStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.Pcrpt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.PcrptBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.PlspId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.SrpIdNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.SymbolicPathName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.identifiers.tlv.LspIdentifiersBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.identifiers.tlv.lsp.identifiers.address.family.Ipv4CaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.identifiers.tlv.lsp.identifiers.address.family.ipv4._case.Ipv4Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.object.Lsp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.object.LspBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.object.lsp.Tlvs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.object.lsp.TlvsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcerr.pcerr.message.error.type.StatefulCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcerr.pcerr.message.error.type.stateful._case.StatefulBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcerr.pcerr.message.error.type.stateful._case.stateful.SrpsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcrpt.message.PcrptMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcrpt.message.pcrpt.message.ReportsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcrpt.message.pcrpt.message.reports.Path;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcrpt.message.pcrpt.message.reports.PathBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.srp.object.Srp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.srp.object.SrpBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.symbolic.path.name.tlv.SymbolicPathNameBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.PcerrBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.EroBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.ero.Subobject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcep.error.object.ErrorObjectBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.PcerrMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.pcerr.message.ErrorsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev130820.Ipv4ExtendedTunnelId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev130820.LspId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev130820.TunnelId;
+
+public final class MsgBuilderUtil {
+
+ private MsgBuilderUtil() {
+ }
+
+ public static Pcrpt createPcRtpMessage(final Lsp lsp, final Optional<Srp> srp, final Path path) {
+ final PcrptBuilder rptBuilder = new PcrptBuilder();
+ final PcrptMessageBuilder msgBuilder = new PcrptMessageBuilder();
+ final ReportsBuilder reportBuilder = new ReportsBuilder();
+ reportBuilder.setLsp(lsp);
+ reportBuilder.setSrp(srp.orNull());
+ reportBuilder.setPath(path);
+ msgBuilder.setReports(Lists.newArrayList(reportBuilder.build()));
+ rptBuilder.setPcrptMessage(msgBuilder.build());
+ return rptBuilder.build();
+ }
+
+ public static Lsp createLsp(final long plspId, final boolean sync, final Optional<Tlvs> tlvs) {
+ final LspBuilder lspBuilder = new LspBuilder();
+ lspBuilder.setAdministrative(true);
+ lspBuilder.setDelegate(true);
+ lspBuilder.setIgnore(false);
+ lspBuilder.setOperational(OperationalStatus.Up);
+ lspBuilder.setPlspId(new PlspId(plspId));
+ lspBuilder.setProcessingRule(false);
+ lspBuilder.setRemove(false);
+ lspBuilder.setSync(sync);
+ lspBuilder.setTlvs(tlvs.orNull());
+ return lspBuilder.build();
+ }
+
+ public static Path createPath(final List<Subobject> subobjects) {
+ final PathBuilder pathBuilder = new PathBuilder();
+ pathBuilder.setEro(new EroBuilder().setSubobject(subobjects).build());
+ return pathBuilder.build();
+ }
+
+ public static Srp createSrp(final long srpId) {
+ final SrpBuilder srpBuilder = new SrpBuilder();
+ srpBuilder.setProcessingRule(false);
+ srpBuilder.setIgnore(false);
+ srpBuilder.setOperationId(new SrpIdNumber(srpId));
+ return srpBuilder.build();
+ }
+
+ public static Path updToRptPath(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcupd.message.pcupd.message.updates.Path path) {
+ final PathBuilder pathBuilder = new PathBuilder();
+ pathBuilder.setBandwidth(path.getBandwidth());
+ pathBuilder.setClassType(path.getClassType());
+ pathBuilder.setEro(path.getEro());
+ pathBuilder.setIro(path.getIro());
+ pathBuilder.setLspa(path.getLspa());
+ pathBuilder.setMetrics(path.getMetrics());
+ pathBuilder.setOf(path.getOf());
+ pathBuilder.setRro(path.getRro());
+ pathBuilder.setXro(path.getXro());
+ return pathBuilder.build();
+ }
+
+ public static Tlvs createLspTlvs(final long lspId, final boolean symbolicPathName, InetAddress tunnelEndpoint,
+ InetAddress tunnelSender, InetAddress extendedTunnelAddress) {
+ final TlvsBuilder tlvs = new TlvsBuilder().setLspIdentifiers(new LspIdentifiersBuilder()
+ .setLspId(new LspId(lspId))
+ .setAddressFamily(
+ new Ipv4CaseBuilder().setIpv4(
+ new Ipv4Builder()
+ .setIpv4TunnelEndpointAddress(new Ipv4Address(tunnelEndpoint.getHostAddress()))
+ .setIpv4TunnelSenderAddress(new Ipv4Address(tunnelSender.getHostAddress()))
+ .setIpv4ExtendedTunnelId(
+ new Ipv4ExtendedTunnelId(extendedTunnelAddress.getHostAddress()))
+ .build()).build()).setTunnelId(new TunnelId((int) lspId)).build());
+ if (symbolicPathName) {
+ tlvs.setSymbolicPathName(new SymbolicPathNameBuilder().setPathName(
+ new SymbolicPathName(Charsets.UTF_8.encode("tunnel" + lspId).array())).build());
+ }
+ return tlvs.build();
+ }
+
+ public static Message createErrorMsg(final PCEPErrors e, final long srpId) {
+ final PcerrMessageBuilder msgBuilder = new PcerrMessageBuilder();
+ return new PcerrBuilder().setPcerrMessage(
+ msgBuilder
+ .setErrorType(
+ new StatefulCaseBuilder().setStateful(
+ new StatefulBuilder().setSrps(
+ Lists.newArrayList(new SrpsBuilder().setSrp(
+ new SrpBuilder().setProcessingRule(false).setIgnore(false)
+ .setOperationId(new SrpIdNumber(srpId)).build())
+ .build())).build()).build())
+ .setErrors(
+ Arrays.asList(new ErrorsBuilder().setErrorObject(
+ new ErrorObjectBuilder().setType(e.getErrorType()).setValue(e.getErrorValue())
+ .build()).build())).build()).build();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. 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.util.ArrayList;
+import java.util.List;
+import org.opendaylight.protocol.pcep.ietf.stateful07.Stateful07SrpObjectParser;
+import org.opendaylight.protocol.pcep.spi.PCEPExtensionProviderContext;
+import org.opendaylight.protocol.pcep.spi.pojo.AbstractPCEPExtensionProviderActivator;
+
+public class PCCActivator extends AbstractPCEPExtensionProviderActivator {
+
+ @Override
+ protected List<AutoCloseable> startImpl(PCEPExtensionProviderContext context) {
+ final List<AutoCloseable> regs = new ArrayList<>();
+ regs.add(context.registerObjectParser(Stateful07SrpObjectParser.CLASS, Stateful07SrpObjectParser.TYPE,
+ new PCCSrpObjectParser(context.getTlvHandlerRegistry(), context.getVendorInformationTlvRegistry())));
+ return regs;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. 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 com.google.common.base.Preconditions;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.util.concurrent.DefaultPromise;
+import io.netty.util.concurrent.Future;
+import io.netty.util.concurrent.GlobalEventExecutor;
+import io.netty.util.concurrent.Promise;
+import java.net.InetSocketAddress;
+import org.opendaylight.protocol.framework.AbstractDispatcher;
+import org.opendaylight.protocol.framework.ProtocolSession;
+import org.opendaylight.protocol.framework.ReconnectStrategy;
+import org.opendaylight.protocol.framework.SessionListener;
+import org.opendaylight.protocol.framework.SessionListenerFactory;
+import org.opendaylight.protocol.framework.SessionNegotiatorFactory;
+import org.opendaylight.protocol.pcep.impl.PCEPHandlerFactory;
+import org.opendaylight.protocol.pcep.impl.PCEPSessionImpl;
+
+public class PCCMock<M, S extends ProtocolSession<M>, L extends SessionListener<M, ?, ?>> extends
+ AbstractDispatcher<S, L> {
+
+ private final SessionNegotiatorFactory<M, S, L> negotiatorFactory;
+ private final PCEPHandlerFactory factory;
+
+ public PCCMock(final SessionNegotiatorFactory<M, S, L> negotiatorFactory, final PCEPHandlerFactory factory,
+ final DefaultPromise<PCEPSessionImpl> defaultPromise) {
+ super(GlobalEventExecutor.INSTANCE, new NioEventLoopGroup(), new NioEventLoopGroup());
+ this.negotiatorFactory = Preconditions.checkNotNull(negotiatorFactory);
+ this.factory = Preconditions.checkNotNull(factory);
+ }
+
+ public Future<S> createClient(final InetSocketAddress address, final ReconnectStrategy strategy,
+ final SessionListenerFactory<L> listenerFactory) {
+ return super.createClient(address, strategy, new PipelineInitializer<S>() {
+ @Override
+ public void initializeChannel(final SocketChannel ch, final Promise<S> promise) {
+ ch.pipeline().addLast(PCCMock.this.factory.getDecoders());
+ ch.pipeline().addLast("negotiator",
+ PCCMock.this.negotiatorFactory.getSessionNegotiator(listenerFactory, ch, promise));
+ ch.pipeline().addLast(PCCMock.this.factory.getEncoders());
+ }
+ });
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. 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 com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import org.opendaylight.protocol.pcep.ietf.stateful07.Stateful07SrpObjectParser;
+import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
+import org.opendaylight.protocol.pcep.spi.TlvRegistry;
+import org.opendaylight.protocol.pcep.spi.VendorInformationTlvRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.SrpIdNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.srp.object.Srp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.srp.object.SrpBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.srp.object.srp.TlvsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.ObjectHeader;
+
+public class PCCSrpObjectParser extends Stateful07SrpObjectParser {
+
+ protected PCCSrpObjectParser(TlvRegistry tlvReg, VendorInformationTlvRegistry viTlvReg) {
+ super(tlvReg, viTlvReg);
+ }
+
+ @Override
+ public Srp parseObject(ObjectHeader header, ByteBuf bytes) throws PCEPDeserializerException {
+ Preconditions.checkArgument(bytes != null && bytes.isReadable(),
+ "Array of bytes is mandatory. Can't be null or empty.");
+ if (bytes.readableBytes() < MIN_SIZE) {
+ throw new PCEPDeserializerException("Wrong length of array of bytes. Passed: " + bytes.readableBytes()
+ + "; Expected: >=" + MIN_SIZE + ".");
+ }
+ final SrpBuilder builder = new SrpBuilder();
+ builder.setIgnore(header.isIgnore());
+ builder.setProcessingRule(header.isProcessingRule());
+ bytes.readerIndex(bytes.readerIndex() + FLAGS_SIZE);
+ builder.setOperationId(new SrpIdNumber(bytes.readUnsignedInt()));
+ final TlvsBuilder tlvsBuilder = new TlvsBuilder();
+ parseTlvs(tlvsBuilder, bytes.slice());
+ builder.setTlvs(tlvsBuilder.build());
+ return builder.build();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. 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 static org.opendaylight.protocol.pcep.pcc.mock.MsgBuilderUtil.createLsp;
+import static org.opendaylight.protocol.pcep.pcc.mock.MsgBuilderUtil.createLspTlvs;
+import static org.opendaylight.protocol.pcep.pcc.mock.MsgBuilderUtil.createPath;
+import static org.opendaylight.protocol.pcep.pcc.mock.MsgBuilderUtil.createPcRtpMessage;
+import static org.opendaylight.protocol.pcep.pcc.mock.MsgBuilderUtil.createSrp;
+import static org.opendaylight.protocol.pcep.pcc.mock.MsgBuilderUtil.updToRptPath;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import org.opendaylight.protocol.pcep.PCEPSession;
+import org.opendaylight.protocol.pcep.PCEPSessionListener;
+import org.opendaylight.protocol.pcep.PCEPTerminationReason;
+import org.opendaylight.protocol.pcep.spi.PCEPErrors;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.Pcrpt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.Pcupd;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.object.LspBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.object.lsp.Tlvs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcupd.message.pcupd.message.Updates;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.srp.object.Srp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.ero.Subobject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev130820.basic.explicit.route.subobjects.subobject.type.IpPrefixCase;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SimpleSessionListener implements PCEPSessionListener {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SimpleSessionListener.class);
+
+ private final int pccNumber;
+ private final int lspsCount;
+ private final boolean pcError;
+ private final InetAddress address;
+
+ public SimpleSessionListener(final int lspsCount, final boolean pcError, final int pccNumber,
+ final InetAddress address) {
+ Preconditions.checkArgument(lspsCount > 0);
+ this.lspsCount = lspsCount;
+ this.pcError = pcError;
+ this.pccNumber = pccNumber;
+ this.address = address;
+ }
+
+ @Override
+ public void onMessage(final PCEPSession session, final Message message) {
+ LOG.debug("Received message: {}", message);
+ if (message instanceof Pcupd) {
+ final Pcupd updMsg = (Pcupd) message;
+ final Updates updates = updMsg.getPcupdMessage().getUpdates().get(0);
+ final long srpId = updates.getSrp().getOperationId().getValue();
+ if (pcError) {
+ session.sendMessage(MsgBuilderUtil.createErrorMsg(getRandomError(), srpId));
+ } else {
+ final Tlvs tlvs = createLspTlvs(updates.getLsp().getPlspId().getValue(), false,
+ getDestinationAddress(updates.getPath().getEro().getSubobject()), this.address, this.address);
+ final Pcrpt pcRpt = createPcRtpMessage(new LspBuilder(updates.getLsp()).setTlvs(tlvs).build(),
+ Optional.fromNullable(createSrp(srpId)), updToRptPath(updates.getPath()));
+ session.sendMessage(pcRpt);
+ }
+ }
+ }
+
+ @Override
+ public void onSessionUp(final PCEPSession session) {
+ LOG.debug("Session up.");
+ for (int i = 1; i <= this.lspsCount; i++) {
+ final Tlvs tlvs = MsgBuilderUtil.createLspTlvs(i * this.pccNumber, true, this.address, this.address,
+ this.address);
+ session.sendMessage(createPcRtpMessage(
+ createLsp(i * this.pccNumber, true, Optional.<Tlvs> fromNullable(tlvs)), Optional.<Srp> absent(),
+ createPath(Collections.<Subobject> emptyList())));
+ }
+ // end-of-sync marker
+ session.sendMessage(createPcRtpMessage(createLsp(0, false, Optional.<Tlvs> absent()), Optional.<Srp> absent(),
+ createPath(Collections.<Subobject> emptyList())));
+ }
+
+ @Override
+ public void onSessionDown(final PCEPSession session, final Exception e) {
+ LOG.debug("Session down with cause : {} or exception: {}", e.getCause(), e, e);
+ session.close();
+ }
+
+ @Override
+ public void onSessionTerminated(final PCEPSession session, final PCEPTerminationReason cause) {
+ LOG.debug("Session terminated. Cause : {}", cause.toString());
+ }
+
+ private InetAddress getDestinationAddress(final List<Subobject> subobjects) {
+ if (subobjects != null && !subobjects.isEmpty()) {
+ final String prefix = ((IpPrefixCase) subobjects.get(subobjects.size() - 1).getSubobjectType())
+ .getIpPrefix().getIpPrefix().getIpv4Prefix().getValue();
+ try {
+ return InetAddress.getByName(prefix.substring(0, prefix.indexOf('/')));
+ } catch (UnknownHostException e) {
+ LOG.debug("Unknown host name {}", prefix);
+ }
+ }
+ return this.address;
+ }
+
+ private Random rnd = new Random();
+
+ private PCEPErrors getRandomError() {
+ return PCEPErrors.values()[rnd.nextInt(PCEPErrors.values().length)];
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. 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 static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+
+import com.google.common.collect.Lists;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.List;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.opendaylight.protocol.pcep.PCEPSession;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.Pcrpt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.Pcupd;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.PcupdBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.PlspId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.SrpIdNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.object.LspBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcupd.message.PcupdMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcupd.message.pcupd.message.UpdatesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcupd.message.pcupd.message.updates.PathBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.srp.object.SrpBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Pcerr;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.EroBuilder;
+
+public class SimpleSessionListenerTest {
+
+ private static final String IP_ADDRESS = "127.0.0.1";
+
+ @Mock
+ private PCEPSession mockedSession;
+
+ private final List<Message> sendMessages = Lists.newArrayList();
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ Mockito.doAnswer(new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) throws Throwable {
+ SimpleSessionListenerTest.this.sendMessages.add((Message) invocation.getArguments()[0]);
+ return null;
+ }
+ }).when(mockedSession).sendMessage(Mockito.any(Message.class));
+ }
+
+ @After
+ public void cleanup() {
+ this.sendMessages.clear();
+ }
+
+ @Test
+ public void testSessionListenerPcRpt() throws UnknownHostException {
+ final SimpleSessionListener sessionListser = new SimpleSessionListener(1, false, 1,
+ InetAddress.getByName(IP_ADDRESS));
+
+ sessionListser.onSessionUp(this.mockedSession);
+ // one lsp + end-of-sync marker
+ Mockito.verify(this.mockedSession, Mockito.times(2)).sendMessage(Mockito.any(Message.class));
+ assertEquals(2, this.sendMessages.size());
+ assertTrue(this.sendMessages.get(0) instanceof Pcrpt);
+ assertTrue(this.sendMessages.get(1) instanceof Pcrpt);
+
+ sessionListser.onMessage(this.mockedSession, createUpdMsg());
+ // send PcRpt as a response to PcUpd
+ Mockito.verify(this.mockedSession, Mockito.times(3)).sendMessage(Mockito.any(Message.class));
+ assertEquals(3, this.sendMessages.size());
+ assertTrue(this.sendMessages.get(2) instanceof Pcrpt);
+ }
+
+ @Test
+ public void testSessionListenerPcErr() throws UnknownHostException {
+ final SimpleSessionListener sessionListser = new SimpleSessionListener(1, true, 1,
+ InetAddress.getByName(IP_ADDRESS));
+
+ sessionListser.onMessage(this.mockedSession, createUpdMsg());
+ // send PcErr as a response to PcUpd
+ Mockito.verify(this.mockedSession, Mockito.times(1)).sendMessage(Mockito.any(Message.class));
+ assertEquals(1, this.sendMessages.size());
+ assertTrue(this.sendMessages.get(0) instanceof Pcerr);
+ }
+
+ private Pcupd createUpdMsg() {
+ final PcupdMessageBuilder msgBuilder = new PcupdMessageBuilder();
+ final UpdatesBuilder updsBuilder = new UpdatesBuilder();
+ updsBuilder.setLsp(new LspBuilder().setPlspId(new PlspId(1L)).build());
+ final PathBuilder pathBuilder = new PathBuilder();
+ pathBuilder.setEro(new EroBuilder().build());
+ updsBuilder.setPath(pathBuilder.build());
+ updsBuilder.setSrp(new SrpBuilder().setOperationId(new SrpIdNumber(0L)).build());
+ msgBuilder.setUpdates(Lists.newArrayList(updsBuilder.build()));
+ return new PcupdBuilder().setPcupdMessage(msgBuilder.build()).build();
+ }
+}
<module>controller-config</module>
<module>segment-routing</module>
+ <module>pcc-mock</module>
</modules>
<dependencyManagement>