BUG-2208: PCC-MOCK Stateful Sync Opt 91/30491/25
authorClaudio D. Gasparini <cgaspari@cisco.com>
Sat, 28 Nov 2015 21:33:05 +0000 (22:33 +0100)
committerMilos Fabian <milfabia@cisco.com>
Sun, 17 Jan 2016 22:23:53 +0000 (22:23 +0000)
Update pcc-mock to support:
+State Synchronization Avoidance.
+Incremental Synchronization
+PCE Triggered Initial Synchronization
+PCE Triggered Lsp Resynchronization
+PCE Triggered Full DB Resynchronization
Input
--state-sync-avoidance 10 5 5
--incremental-sync-procedure 10 5 5
--triggered-initial-sync
--triggered-re-sync
+DBVersion number after PCC reconnection
+Seconds to wait until disconnect
+Seconds to wait until PCC reconnects

Change-Id: I61f673177a086d969b6f097733351413b71ea8e2
Signed-off-by: Claudio D. Gasparini <cgaspari@cisco.com>
28 files changed:
pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/Main.java
pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/MsgBuilderUtil.java
pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/PCCSyncOptimization.java [new file with mode: 0644]
pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/PCCTunnel.java [new file with mode: 0644]
pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/PCCTunnelBuilder.java [new file with mode: 0644]
pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/PCCTunnelManagerImpl.java
pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/PCCsBuilder.java [new file with mode: 0644]
pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/TimerHandler.java [new file with mode: 0644]
pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/api/LspType.java [new file with mode: 0644]
pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/api/PCCDispatcher.java [moved from pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/api/PccDispatcher.java with 63% similarity]
pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/api/PCCSession.java [moved from pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/api/PccSession.java with 76% similarity]
pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/api/PCCTunnelManager.java [moved from pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/api/PccTunnelManager.java with 60% similarity]
pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/protocol/PCCDispatcherImpl.java [moved from pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/PCCDispatcherImpl.java with 82% similarity]
pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/protocol/PCCPeerProposal.java [new file with mode: 0644]
pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/protocol/PCCReconnectPromise.java [moved from pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/PCCReconnectPromise.java with 98% similarity]
pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/protocol/PCCServerPeerProposal.java [new file with mode: 0644]
pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/protocol/PCCSessionListener.java [moved from pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/PCCSessionListener.java with 68% similarity]
pcep/pcc-mock/src/test/java/org/opendaylight/protocol/pcep/pcc/mock/PCCDispatcherImplTest.java
pcep/pcc-mock/src/test/java/org/opendaylight/protocol/pcep/pcc/mock/PCCIncrementalSyncTest.java [new file with mode: 0644]
pcep/pcc-mock/src/test/java/org/opendaylight/protocol/pcep/pcc/mock/PCCMockCommon.java [new file with mode: 0644]
pcep/pcc-mock/src/test/java/org/opendaylight/protocol/pcep/pcc/mock/PCCMockTest.java
pcep/pcc-mock/src/test/java/org/opendaylight/protocol/pcep/pcc/mock/PCCSessionListenerTest.java
pcep/pcc-mock/src/test/java/org/opendaylight/protocol/pcep/pcc/mock/PCCSyncAvoidanceProcedureTest.java [new file with mode: 0644]
pcep/pcc-mock/src/test/java/org/opendaylight/protocol/pcep/pcc/mock/PCCTriggeredFullDBResyncTest.java [new file with mode: 0644]
pcep/pcc-mock/src/test/java/org/opendaylight/protocol/pcep/pcc/mock/PCCTriggeredLspResyncTest.java [new file with mode: 0644]
pcep/pcc-mock/src/test/java/org/opendaylight/protocol/pcep/pcc/mock/PCCTriggeredSyncTest.java [new file with mode: 0644]
pcep/pcc-mock/src/test/java/org/opendaylight/protocol/pcep/pcc/mock/PCCTunnelManagerImplTest.java
pcep/testtool/src/test/java/org/opendaylight/protocol/pcep/testtool/PCCMock.java

index 4cfd1cf35e75908678cf3a091578877c7aa55676..d10d84149d130c217d5075f78f9fef9131d3d3fa 100644 (file)
@@ -8,19 +8,17 @@
 
 package org.opendaylight.protocol.pcep.pcc.mock;
 
-import static com.google.common.base.Strings.isNullOrEmpty;
-
 import ch.qos.logback.classic.Level;
 import ch.qos.logback.classic.LoggerContext;
-import com.google.common.base.Charsets;
 import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.common.net.HostAndPort;
 import com.google.common.net.InetAddresses;
-import io.netty.util.HashedWheelTimer;
-import io.netty.util.Timer;
+import java.math.BigInteger;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.UnknownHostException;
@@ -29,19 +27,7 @@ import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import org.opendaylight.protocol.pcep.PCEPCapability;
-import org.opendaylight.protocol.pcep.PCEPSessionListener;
-import org.opendaylight.protocol.pcep.PCEPSessionListenerFactory;
-import org.opendaylight.protocol.pcep.PCEPSessionNegotiatorFactory;
-import org.opendaylight.protocol.pcep.ietf.initiated00.CrabbeInitiatedActivator;
 import org.opendaylight.protocol.pcep.ietf.stateful07.PCEPStatefulCapability;
-import org.opendaylight.protocol.pcep.ietf.stateful07.StatefulActivator;
-import org.opendaylight.protocol.pcep.impl.BasePCEPSessionProposalFactory;
-import org.opendaylight.protocol.pcep.impl.DefaultPCEPSessionNegotiatorFactory;
-import org.opendaylight.protocol.pcep.impl.PCEPSessionImpl;
-import org.opendaylight.protocol.pcep.pcc.mock.api.PccTunnelManager;
-import org.opendaylight.protocol.pcep.spi.PCEPExtensionProviderContext;
-import org.opendaylight.protocol.pcep.spi.pojo.ServiceLoaderPCEPExtensionProviderContext;
-import org.opendaylight.tcpmd5.api.KeyMapping;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -54,11 +40,18 @@ public final class Main {
     private static final short DEFAULT_KEEP_ALIVE = 30;
     private static final short DEFAULT_DEAD_TIMER = 120;
     private static final InetAddress LOCALHOST = InetAddresses.forString("127.0.0.1");
-    private static final PCEPCapability STATEFUL_CAPABILITY = new PCEPStatefulCapability(true, true, true,
-            false, false, false, false);
-    private static final List<PCEPCapability> CAPABILITIES = Lists.newArrayList(STATEFUL_CAPABILITY);
+    private static boolean TRIGGERED_INIT_SYNC = Boolean.FALSE;
+    private static boolean INCLUDE_DBV = Boolean.FALSE;
+    private static boolean INCREMENTAL_SYNC = Boolean.FALSE;
+    private static boolean TRIGGERED_RESYNC = Boolean.FALSE;
+    private static BigInteger SYNC_OPT_DB_VERSION;
+    private static int RECONNECT_AFTER_X_SECOND;
+    private static int DISCONNECT_AFTER_X_SECONDS;
+
 
-    private Main() { }
+    private Main() {
+        throw new UnsupportedOperationException();
+    }
 
     public static void main(final String[] args) throws InterruptedException, ExecutionException, UnknownHostException {
         InetSocketAddress localAddress = new InetSocketAddress(LOCALHOST, DEFAULT_LOCAL_PORT);
@@ -73,7 +66,6 @@ public final class Main {
         long reconnectTime = -1;
         int redelegationTimeout = 0;
         int stateTimeout = -1;
-        final Timer timer = new HashedWheelTimer();
 
         getRootLogger(lc).setLevel(ch.qos.logback.classic.Level.INFO);
         int argIdx = 0;
@@ -97,51 +89,57 @@ public final class Main {
             } else if (args[argIdx].equals("--password")) {
                 password = args[++argIdx];
             } else if (args[argIdx].equals("--reconnect")) {
-                reconnectTime =  TimeUnit.SECONDS.toMillis(Integer.valueOf(args[++argIdx]).intValue());
+                reconnectTime = TimeUnit.SECONDS.toMillis(Integer.valueOf(args[++argIdx]).intValue());
             } else if (args[argIdx].equals("--redelegation-timeout")) {
                 redelegationTimeout = Integer.valueOf(args[++argIdx]);
             } else if (args[argIdx].equals("--state-timeout")) {
                 stateTimeout = Integer.valueOf(args[++argIdx]);
+            } else if (args[argIdx].equals("--state-sync-avoidance")) {
+                //"--state-sync-avoidance 10, 5, 10
+                INCLUDE_DBV = Boolean.TRUE;
+                final Long dbVersionAfterReconnect = Long.valueOf(args[++argIdx]);
+                DISCONNECT_AFTER_X_SECONDS = Integer.valueOf(args[++argIdx]);
+                RECONNECT_AFTER_X_SECOND = Integer.valueOf(args[++argIdx]);
+                SYNC_OPT_DB_VERSION = BigInteger.valueOf(dbVersionAfterReconnect);
+            } else if (args[argIdx].equals("--incremental-sync-procedure")) {
+                //TODO Check that DBv > Lsp always ??
+                INCLUDE_DBV = Boolean.TRUE;
+                INCREMENTAL_SYNC = Boolean.TRUE;
+                //Version of database to be used after restart
+                final Long initialDbVersionAfterReconnect = Long.valueOf(args[++argIdx]);
+                DISCONNECT_AFTER_X_SECONDS = Integer.valueOf(args[++argIdx]);
+                RECONNECT_AFTER_X_SECOND = Integer.valueOf(args[++argIdx]);
+                SYNC_OPT_DB_VERSION = BigInteger.valueOf(initialDbVersionAfterReconnect);
+            } else if (args[argIdx].equals("--triggered-initial-sync")) {
+                TRIGGERED_INIT_SYNC = Boolean.TRUE;
+            } else if (args[argIdx].equals("--triggered-re-sync")) {
+                TRIGGERED_RESYNC = Boolean.TRUE;
             } else {
                 LOG.warn("WARNING: Unrecognized argument: {}", args[argIdx]);
             }
             argIdx++;
         }
-        createPCCs(lsps, pcError, pccCount, localAddress, remoteAddress, ka, dt, password, reconnectTime, redelegationTimeout, stateTimeout, timer);
-    }
 
-    public static void createPCCs(final int lspsPerPcc, final boolean pcerr, final int pccCount,
-            final InetSocketAddress localAddress, final List<InetSocketAddress> remoteAddress, final short keepalive, final short deadtimer,
-            final String password, final long reconnectTime, final int redelegationTimeout, final int stateTimeout, final Timer timer) throws InterruptedException, ExecutionException {
-        startActivators();
-        InetAddress currentAddress = localAddress.getAddress();
-        final PCCDispatcherImpl pccDispatcher = new PCCDispatcherImpl(ServiceLoaderPCEPExtensionProviderContext.getSingletonInstance().getMessageHandlerRegistry());
-        for (int i = 0; i < pccCount; i++) {
-            final PccTunnelManager tunnelManager = new PCCTunnelManagerImpl(lspsPerPcc, currentAddress,
-                    redelegationTimeout, stateTimeout, timer);
-            createPCC(pcerr, new InetSocketAddress(currentAddress, localAddress.getPort()),
-                    remoteAddress, getSessionNegotiatorFactory(keepalive, deadtimer), pccDispatcher, password, reconnectTime, tunnelManager);
-            currentAddress = InetAddresses.increment(currentAddress);
+        if (INCREMENTAL_SYNC) {
+            Preconditions.checkArgument(SYNC_OPT_DB_VERSION.intValue() > lsps, "Synchronization Database Version which will be used after " +
+                "reconnectes requires to be higher than lsps");
         }
-    }
 
-    private static void createPCC(final boolean pcerr, final InetSocketAddress localAddress,
-            final List<InetSocketAddress> remoteAddress, final PCEPSessionNegotiatorFactory<PCEPSessionImpl> snf, final PCCDispatcherImpl pccDispatcher,
-            final String password, final long reconnectTime, final PccTunnelManager tunnelManager) throws InterruptedException, ExecutionException {
-
-        for (final InetSocketAddress pceAddress : remoteAddress) {
-            pccDispatcher.createClient(pceAddress, reconnectTime,
-                    new PCEPSessionListenerFactory() {
-                        @Override
-                        public PCEPSessionListener getSessionListener() {
-                            return new PCCSessionListener(remoteAddress.indexOf(pceAddress), tunnelManager, pcerr);
-                        }
-                    }, snf, getKeyMapping(pceAddress.getAddress(), password), localAddress);
+        final Optional<BigInteger> dBVersion = Optional.fromNullable(SYNC_OPT_DB_VERSION);
+        final PCCsBuilder pccs = new PCCsBuilder(lsps, pcError, pccCount, localAddress, remoteAddress, ka, dt, password, reconnectTime, redelegationTimeout,
+            stateTimeout, dBVersion, getCapabilities());
+        final TimerHandler timerHandler = new TimerHandler(pccs, dBVersion, DISCONNECT_AFTER_X_SECONDS, RECONNECT_AFTER_X_SECOND);
+        pccs.createPCCs(BigInteger.valueOf(lsps), Optional.fromNullable(timerHandler));
+        if (!TRIGGERED_INIT_SYNC) {
+            timerHandler.createDisconnectTask();
         }
     }
 
-    private static PCEPSessionNegotiatorFactory<PCEPSessionImpl> getSessionNegotiatorFactory(final short keepAlive, final short deadTimer) {
-        return new DefaultPCEPSessionNegotiatorFactory(new BasePCEPSessionProposalFactory(deadTimer, keepAlive, CAPABILITIES), 0);
+    private static PCEPCapability getCapabilities() {
+        if (TRIGGERED_INIT_SYNC) {
+            Preconditions.checkArgument(INCLUDE_DBV);
+        }
+        return new PCEPStatefulCapability(true, true, true, TRIGGERED_INIT_SYNC, TRIGGERED_RESYNC, INCREMENTAL_SYNC, INCLUDE_DBV);
     }
 
     private static ch.qos.logback.classic.Logger getRootLogger(final LoggerContext lc) {
@@ -167,23 +165,4 @@ public final class Main {
         return new InetSocketAddress(hostAndPort.getHostText(), hostAndPort.getPort());
     }
 
-    private static KeyMapping getKeyMapping(final InetAddress inetAddress, final String password) {
-        if (!isNullOrEmpty(password)) {
-            final KeyMapping keyMapping = new KeyMapping();
-            keyMapping.put(inetAddress, password.getBytes(Charsets.US_ASCII));
-            return keyMapping;
-        }
-        return null;
-    }
-
-    private static void startActivators() {
-        final PCCActivator pccActivator = new PCCActivator();
-        final StatefulActivator stateful = new StatefulActivator();
-        final CrabbeInitiatedActivator activator = new CrabbeInitiatedActivator();
-        final PCEPExtensionProviderContext ctx = ServiceLoaderPCEPExtensionProviderContext.getSingletonInstance();
-        pccActivator.start(ctx);
-        stateful.start(ctx);
-        activator.start(ctx);
-    }
-
 }
index a2d7f0a0842e6cf2641757a4354f790b5fa6ffa1..1e63be9293b9762c17ac5b2f8ee66a1b81652b66 100644 (file)
@@ -11,10 +11,15 @@ 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.math.BigInteger;
 import java.util.Arrays;
 import java.util.List;
+import javax.annotation.Nonnull;
 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.controller.pcep.sync.optimizations.rev150714.Tlvs1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.sync.optimizations.rev150714.Tlvs1Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.sync.optimizations.rev150714.lsp.db.version.tlv.LspDbVersionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.pcinitiate.message.pcinitiate.message.Requests;
 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;
@@ -118,7 +123,12 @@ public final class MsgBuilderUtil {
     }
 
     public static Tlvs createLspTlvs(final long lspId, final boolean symbolicPathName, final String tunnelEndpoint,
-            final String tunnelSender, final String extendedTunnelAddress, final Optional<byte[]> symbolicName) {
+                                     final String tunnelSender, final String extendedTunnelAddress, final Optional<byte[]> symbolicName) {
+        return createLspTlvs(lspId, symbolicPathName, tunnelEndpoint, tunnelSender, extendedTunnelAddress, symbolicName, Optional.<BigInteger>absent());
+    }
+
+    public static Tlvs createLspTlvs(final long lspId, final boolean symbolicPathName, final String tunnelEndpoint,
+                                     final String tunnelSender, final String extendedTunnelAddress, final Optional<byte[]> symbolicName, final Optional<BigInteger> lspDBVersion) {
         final TlvsBuilder tlvs = new TlvsBuilder().setLspIdentifiers(new LspIdentifiersBuilder()
                 .setLspId(new LspId(lspId))
                 .setAddressFamily(
@@ -138,10 +148,21 @@ public final class MsgBuilderUtil {
                         new SymbolicPathName(getDefaultPathName(tunnelSender, lspId))).build());
             }
         }
+
+        if (lspDBVersion.isPresent()) {
+            tlvs.addAugmentation(Tlvs1.class, new Tlvs1Builder().setLspDbVersion(new LspDbVersionBuilder().
+                setLspDbVersionValue(lspDBVersion.get()).build()).build());
+        }
         return tlvs.build();
     }
 
-    public static Pcerr createErrorMsg(final PCEPErrors e, final long srpId) {
+    public static Optional<Tlvs> createLspTlvsEndofSync(@Nonnull final BigInteger bigInteger) {
+        final Tlvs tlvs = new TlvsBuilder().addAugmentation(Tlvs1.class, new Tlvs1Builder().setLspDbVersion(
+            new LspDbVersionBuilder().setLspDbVersionValue(bigInteger).build()).build()).build();
+        return Optional.of(tlvs);
+    }
+
+    public static Pcerr createErrorMsg(@Nonnull final PCEPErrors e, @Nonnull final long srpId) {
         final PcerrMessageBuilder msgBuilder = new PcerrMessageBuilder();
         return new PcerrBuilder().setPcerrMessage(
                 msgBuilder
diff --git a/pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/PCCSyncOptimization.java b/pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/PCCSyncOptimization.java
new file mode 100644 (file)
index 0000000..0705b4a
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2015 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.Optional;
+import com.google.common.base.Preconditions;
+import java.math.BigInteger;
+import javax.annotation.Nonnull;
+import org.opendaylight.protocol.pcep.pcc.mock.api.PCCSession;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.sync.optimizations.rev150714.Stateful1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.sync.optimizations.rev150714.Tlvs3;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.sync.optimizations.rev150714.lsp.db.version.tlv.LspDbVersion;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.Tlvs1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.open.Tlvs;
+
+final class PCCSyncOptimization {
+    private final boolean dbVersionMatch;
+    private final boolean isSyncAvoidanceEnabled;
+    private final boolean isDeltaSyncEnabled;
+    private final boolean isTriggeredInitialSynEnable;
+    private final boolean isTriggeredReSyncEnable;
+    private final LspDbVersion localLspDbVersion;
+    private final LspDbVersion remoteLspDbVersion;
+    private BigInteger lspDBVersion = BigInteger.ONE;
+    private Boolean resynchronizing = Boolean.FALSE;
+
+    public PCCSyncOptimization(@Nonnull final PCCSession session) {
+        Preconditions.checkNotNull(session);
+        final Tlvs remote = session.getRemoteTlvs();
+        final Tlvs local = session.localSessionCharacteristics();
+        this.localLspDbVersion = getLspDbVersion(local);
+        this.remoteLspDbVersion = getLspDbVersion(remote);
+        this.dbVersionMatch = compareLspDbVersion(localLspDbVersion, remoteLspDbVersion);
+        this.isSyncAvoidanceEnabled = isSyncAvoidance(local) && isSyncAvoidance(remote);
+        this.isDeltaSyncEnabled = isDeltaSync(local) && isDeltaSync(remote);
+        this.isTriggeredInitialSynEnable = isTriggeredInitialSync(local) && isTriggeredInitialSync(remote) &&
+            (this.isDeltaSyncEnabled || this.isSyncAvoidanceEnabled);
+        this.isTriggeredReSyncEnable = isTriggeredReSync(local) && isTriggeredReSync(remote);
+    }
+
+    public boolean doesLspDbMatch() {
+        return dbVersionMatch;
+    }
+
+    public boolean isSyncAvoidanceEnabled() {
+        return isSyncAvoidanceEnabled;
+    }
+
+    public boolean isDeltaSyncEnabled() {
+        return isDeltaSyncEnabled;
+    }
+
+    public boolean isTriggeredInitSyncEnabled() {
+        return isTriggeredInitialSynEnable;
+    }
+
+    public boolean isTriggeredReSyncEnabled() {
+        return isTriggeredReSyncEnable;
+    }
+
+    public BigInteger getLocalLspDbVersionValue() {
+        if (this.localLspDbVersion == null) {
+            return null;
+        }
+        return this.localLspDbVersion.getLspDbVersionValue();
+    }
+
+    public BigInteger getRemoteLspDbVersionValue() {
+        if (this.remoteLspDbVersion == null) {
+            return BigInteger.ONE;
+        }
+        return this.remoteLspDbVersion.getLspDbVersionValue();
+    }
+
+    public boolean isRemoteLspDbVersionNull() {
+        if (this.remoteLspDbVersion == null) {
+            return true;
+        }
+        return false;
+    }
+
+    private static LspDbVersion getLspDbVersion(final Tlvs openTlvs) {
+        if (openTlvs != null) {
+            final Tlvs3 tlvs3 = openTlvs.getAugmentation(Tlvs3.class);
+            if (tlvs3 != null && tlvs3.getLspDbVersion() != null
+                && tlvs3.getLspDbVersion().getLspDbVersionValue() != null) {
+                return tlvs3.getLspDbVersion();
+            }
+        }
+        return null;
+    }
+
+    private static boolean compareLspDbVersion(final LspDbVersion local, final LspDbVersion remote) {
+        if (local != null && remote != null) {
+            return local.equals(remote);
+        }
+        return false;
+    }
+
+    private static Stateful1 getStateful1(final Tlvs openTlvs) {
+        if (openTlvs != null) {
+            final Tlvs1 tlvs1 = openTlvs.getAugmentation(Tlvs1.class);
+            if (tlvs1 != null && tlvs1.getStateful() != null) {
+                return tlvs1.getStateful().getAugmentation(Stateful1.class);
+            }
+        }
+        return null;
+    }
+
+    private static boolean isSyncAvoidance(final Tlvs openTlvs) {
+        final Stateful1 stateful1 = getStateful1(openTlvs);
+        if (stateful1 != null && stateful1.isIncludeDbVersion() != null) {
+            return stateful1.isIncludeDbVersion();
+        }
+        return false;
+    }
+
+    private static boolean isDeltaSync(final Tlvs openTlvs) {
+        final Stateful1 stateful1 = getStateful1(openTlvs);
+        if (stateful1 != null && stateful1.isDeltaLspSyncCapability() != null) {
+            return stateful1.isDeltaLspSyncCapability();
+        }
+        return false;
+    }
+
+    private static boolean isTriggeredInitialSync(final Tlvs openTlvs) {
+        final Stateful1 stateful1 = getStateful1(openTlvs);
+        if (stateful1 != null && stateful1.isTriggeredInitialSync() != null) {
+            return stateful1.isTriggeredInitialSync();
+        }
+        return false;
+    }
+
+    private static boolean isTriggeredReSync(final Tlvs openTlvs) {
+        final Stateful1 stateful1 = getStateful1(openTlvs);
+        if (stateful1 != null && stateful1.isTriggeredResync() != null) {
+            return stateful1.isTriggeredResync();
+        }
+        return false;
+    }
+
+    public Optional<BigInteger> incrementLspDBVersion() {
+        if (!isSyncAvoidanceEnabled()) {
+            return Optional.absent();
+        } else if (isSyncNeedIt() && getLocalLspDbVersionValue() != null && !this.resynchronizing) {
+            this.lspDBVersion = getLocalLspDbVersionValue();
+            return Optional.of(this.lspDBVersion);
+        } else if (this.resynchronizing) {
+            return Optional.of(this.lspDBVersion);
+        }
+
+        this.lspDBVersion = this.lspDBVersion.add(BigInteger.ONE);
+        return Optional.of(this.lspDBVersion);
+    }
+
+    public boolean isSyncNeedIt() {
+        if (doesLspDbMatch() && !this.resynchronizing) {
+            return false;
+        }
+        return true;
+    }
+
+    public void setResynchronizingState(final Boolean resync) {
+        this.resynchronizing = resync;
+    }
+}
diff --git a/pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/PCCTunnel.java b/pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/PCCTunnel.java
new file mode 100644 (file)
index 0000000..7ae54d3
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2015 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 io.netty.util.Timeout;
+import org.opendaylight.protocol.pcep.pcc.mock.api.LspType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcrpt.message.pcrpt.message.reports.Path;
+
+final class PCCTunnel {
+
+    private final byte[] pathName;
+    private final LspType type;
+    private int delegationHolder;
+    private Path lspState;
+    private Timeout redelegationTimeout;
+    private Timeout stateTimeout;
+
+    public PCCTunnel(final byte[] pathName, final int delegationHolder, final LspType type, final Path lspState) {
+        if (pathName != null) {
+            this.pathName = pathName.clone();
+        } else {
+            this.pathName = null;
+        }
+        this.delegationHolder = delegationHolder;
+        this.type = type;
+        this.lspState = lspState;
+    }
+
+    public byte[] getPathName() {
+        return this.pathName;
+    }
+
+    public int getDelegationHolder() {
+        return this.delegationHolder;
+    }
+
+    public void setDelegationHolder(final int delegationHolder) {
+        this.delegationHolder = delegationHolder;
+    }
+
+    public LspType getType() {
+        return this.type;
+    }
+
+    public Path getLspState() {
+        return this.lspState;
+    }
+
+    public void setLspState(final Path lspState) {
+        this.lspState = lspState;
+    }
+
+    public void setRedelegationTimeout(final Timeout redelegationTimeout) {
+        this.redelegationTimeout = redelegationTimeout;
+    }
+
+    public void setStateTimeout(final Timeout stateTimeout) {
+        this.stateTimeout = stateTimeout;
+    }
+
+    public void cancelTimeouts() {
+        if (this.redelegationTimeout != null) {
+            this.redelegationTimeout.cancel();
+        }
+        if (this.stateTimeout != null) {
+            this.stateTimeout.cancel();
+        }
+    }
+}
diff --git a/pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/PCCTunnelBuilder.java b/pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/PCCTunnelBuilder.java
new file mode 100644 (file)
index 0000000..b42400f
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015 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.createPath;
+
+import com.google.common.collect.Lists;
+import java.util.HashMap;
+import java.util.Map;
+import org.opendaylight.protocol.pcep.pcc.mock.api.LspType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+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.types.rev131005.explicit.route.object.ero.Subobject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.ero.SubobjectBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.IpPrefixCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.ip.prefix._case.IpPrefixBuilder;
+
+public class PCCTunnelBuilder {
+    private static final Subobject DEFAULT_ENDPOINT_HOP = getDefaultEROEndpointHop();
+    private static final String ENDPOINT_ADDRESS = "1.1.1.1";
+    private static final String ENDPOINT_PREFIX = ENDPOINT_ADDRESS + "/32";
+    public static final int PCC_DELEGATION = -1;
+
+    public static Map<PlspId, PCCTunnel> createTunnels(String address, final int lsps) {
+        final Map<PlspId, PCCTunnel> tunnels = new HashMap<>();
+        for (int i = 1; i <= lsps; i++) {
+            final PCCTunnel tunnel = new PCCTunnel(MsgBuilderUtil.getDefaultPathName(address, i), PCC_DELEGATION, LspType.PCC_LSP,
+                createPath(Lists.newArrayList(DEFAULT_ENDPOINT_HOP)));
+            tunnels.put(new PlspId((long) i), tunnel);
+        }
+        return tunnels;
+    }
+
+    private static Subobject getDefaultEROEndpointHop() {
+        final SubobjectBuilder builder = new SubobjectBuilder();
+        builder.setLoose(false);
+        builder.setSubobjectType(new IpPrefixCaseBuilder().setIpPrefix(new IpPrefixBuilder().setIpPrefix(
+            new IpPrefix(new Ipv4Prefix(ENDPOINT_PREFIX))).build()).build());
+        return builder.build();
+    }
+}
index 700cb885cc8bf7a275a7d8750ee8c1a7111c348f..50cfded4f1a61ca263ea557291be1a3fb6890008 100644 (file)
@@ -10,6 +10,7 @@ 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.createLspTlvsEndofSync;
 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;
@@ -18,11 +19,11 @@ import static org.opendaylight.protocol.pcep.pcc.mock.MsgBuilderUtil.updToRptPat
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
 import com.google.common.net.InetAddresses;
 import io.netty.util.Timeout;
 import io.netty.util.Timer;
 import io.netty.util.TimerTask;
+import java.math.BigInteger;
 import java.net.InetAddress;
 import java.util.Collections;
 import java.util.HashMap;
@@ -31,12 +32,12 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
+import javax.annotation.Nonnull;
 import javax.annotation.concurrent.GuardedBy;
-import org.opendaylight.protocol.pcep.pcc.mock.api.PccSession;
-import org.opendaylight.protocol.pcep.pcc.mock.api.PccTunnelManager;
+import org.opendaylight.protocol.pcep.pcc.mock.api.LspType;
+import org.opendaylight.protocol.pcep.pcc.mock.api.PCCSession;
+import org.opendaylight.protocol.pcep.pcc.mock.api.PCCTunnelManager;
 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.Lsp1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.Lsp1Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.Srp1;
@@ -45,6 +46,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.cra
 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.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.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;
@@ -54,51 +56,39 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.iet
 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.types.rev131005.explicit.route.object.ero.Subobject;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.ero.SubobjectBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.IpPrefixCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.IpPrefixCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.ip.prefix._case.IpPrefixBuilder;
 
-public class PCCTunnelManagerImpl implements PccTunnelManager {
-
-    private static final Subobject DEFAULT_ENDPOINT_HOP = getDefaultEROEndpointHop();
-    private static final String ENDPOINT_ADDRESS = "1.1.1.1";
-    private static final String ENDPOINT_PREFIX = ENDPOINT_ADDRESS + "/32";
-    private static final Optional<Srp> NO_SRP = Optional.<Srp> absent();
-    private static final int PCC_DELEGATION = -1;
-
-    @GuardedBy("this")
-    private final Map<Integer, PccSession> sessions = new HashMap<>();
+final public class PCCTunnelManagerImpl implements PCCTunnelManager {
 
+    private static final Optional<Srp> NO_SRP = Optional.absent();
     @GuardedBy("this")
-    private final Map<PlspId, Tunnel> tunnels = new HashMap<>();
-
+    private final Map<Integer, PCCSession> sessions = new HashMap<>();
     private final AtomicLong plspIDsCounter;
     private final String address;
     private final Timer timer;
     private final int redelegationTimeout;
     private final int stateTimeout;
+    private final int lspsCount;
+    private final Optional<TimerHandler> timerHandler;
+    @GuardedBy("this")
+    private final Map<PlspId, PCCTunnel> tunnels = new HashMap<>();
+    private PCCSyncOptimization syncOptimization;
 
     public PCCTunnelManagerImpl(final int lspsCount, final InetAddress address, final int redelegationTimeout,
-                                final int stateTimeout, final Timer timer) {
+                                final int stateTimeout, final Timer timer, final Optional<TimerHandler> timerHandler) {
         Preconditions.checkArgument(lspsCount >= 0);
-        Preconditions.checkNotNull(address);
         this.redelegationTimeout = redelegationTimeout;
         this.stateTimeout = stateTimeout;
         this.plspIDsCounter = new AtomicLong(lspsCount);
         this.address = InetAddresses.toAddrString(Preconditions.checkNotNull(address));
         this.timer = Preconditions.checkNotNull(timer);
-        for (int i = 1; i <= lspsCount; i++) {
-            final Tunnel tunnel = new Tunnel(MsgBuilderUtil.getDefaultPathName(this.address, i), PCC_DELEGATION, LspType.PCC_LSP,
-                    createPath(Lists.newArrayList(DEFAULT_ENDPOINT_HOP)));
-            this.tunnels.put(new PlspId((long) i), tunnel);
-        }
+        this.timerHandler = timerHandler;
+        this.lspsCount = lspsCount;
     }
 
-    @Override
-    public void reportToAll(final Updates update, final PccSession session) {
+    protected void reportToAll(final Updates update, final PCCSession session) {
         final PlspId plspId = update.getLsp().getPlspId();
-        final Tunnel tunnel = this.tunnels.get(plspId);
+        final PCCTunnel tunnel = this.tunnels.get(plspId);
         final long srpId = update.getSrp().getOperationId().getValue();
         if (tunnel != null) {
             if (hasDelegation(tunnel, session)) {
@@ -117,21 +107,18 @@ public class PCCTunnelManagerImpl implements PccTunnelManager {
         }
     }
 
-    @Override
-    public void returnDelegation(final Updates update, final PccSession session) {
+    private void returnDelegation(final Updates update, final PCCSession session) {
         final PlspId plspId = update.getLsp().getPlspId();
-        final Tunnel tunnel = this.tunnels.get(plspId);
+        final PCCTunnel tunnel = this.tunnels.get(plspId);
         final long srpId = update.getSrp().getOperationId().getValue();
         if (tunnel != null) {
             //check if session really has a delegation
             if (hasDelegation(tunnel, session)) {
                 //send report D=0
-                final Tlvs tlvs = createLspTlvs(plspId.getValue(), true,
-                        getDestinationAddress(tunnel.getLspState().getEro().getSubobject(), this.address), this.address,
-                        this.address, Optional.of(tunnel.getPathName()));
-                session.sendReport(createPcRtpMessage(
-                        new LspBuilder(update.getLsp()).setSync(true).setOperational(OperationalStatus.Up).setDelegate(false).setTlvs(tlvs).build(),
-                        Optional.of(createSrp(srpId)), tunnel.getLspState()));
+                final Tlvs tlvs = buildTlvs(tunnel, plspId.getValue(), Optional.<List<Subobject>>absent());
+                final Pcrpt pcrtp = createPcRtpMessage(new LspBuilder(update.getLsp()).setSync(true).setOperational(OperationalStatus.Up).setDelegate(false).
+                    setTlvs(tlvs).build(), Optional.of(createSrp(srpId)), tunnel.getLspState());
+                session.sendReport(pcrtp);
                 //start state timer
                 startStateTimeout(tunnel, plspId);
                 //if PCC's LSP, start re-delegation timer
@@ -149,56 +136,21 @@ public class PCCTunnelManagerImpl implements PccTunnelManager {
         }
     }
 
-    @Override
-    public synchronized void onSessionUp(final PccSession session) {
-        //first session - delegate all PCC's LSPs
-        //only when reporting at startup
-        if (! this.sessions.containsKey(session.getId()) && session.getId() == 0) {
-            for (final PlspId plspId : this.tunnels.keySet()) {
-                setDelegation(plspId, session);
-            }
-        }
-        this.sessions.put(session.getId(), session);
-        if (!this.tunnels.isEmpty()) {
-            //report all known LSPs
-            for (final Entry<PlspId, Tunnel> entry : this.tunnels.entrySet()) {
-                final Tunnel tunnel = entry.getValue();
-                final boolean delegation = hasDelegation(tunnel, session);
-                if (delegation) {
-                    tunnel.cancelTimeouts();
-                }
-                final long plspId = entry.getKey().getValue();
-                final Tlvs tlvs = MsgBuilderUtil.createLspTlvs(plspId, true,
-                        getDestinationAddress(tunnel.getLspState().getEro().getSubobject(), this.address), this.address,
-                        this.address, Optional.of(tunnel.getPathName()));
-                session.sendReport(createPcRtpMessage(
-                        createLsp(plspId, true, Optional.<Tlvs> fromNullable(tlvs), delegation, false), NO_SRP,
-                        tunnel.getLspState()));
-            }
-            //end-of-sync marker
-            session.sendReport(createPcRtpMessage(createLsp(0, false, Optional.<Tlvs> absent(), true, false), NO_SRP,
-                    createPath(Collections.<Subobject> emptyList())));
-        }
-    }
-
-    @Override
-    public void takeDelegation(final Requests request, final PccSession session) {
+    protected void takeDelegation(final Requests request, final PCCSession session) {
         final PlspId plspId = request.getLsp().getPlspId();
-        final Tunnel tunnel = this.tunnels.get(plspId);
+        final PCCTunnel tunnel = this.tunnels.get(plspId);
         final long srpId = request.getSrp().getOperationId().getValue();
         if (tunnel != null) {
             //check if tunnel has no delegation
-            if (tunnel.type == LspType.PCE_LSP && (tunnel.getDelegationHolder() == -1 || tunnel.getDelegationHolder() == session.getId())) {
+            if (tunnel.getType() == LspType.PCE_LSP && (tunnel.getDelegationHolder() == -1 || tunnel.getDelegationHolder() == session.getId())) {
                 //set delegation
                 tunnel.cancelTimeouts();
                 setDelegation(plspId, session);
                 //send report
-                final Tlvs tlvs = createLspTlvs(plspId.getValue(), true,
-                        getDestinationAddress(tunnel.getLspState().getEro().getSubobject(), this.address), this.address,
-                        this.address, Optional.of(tunnel.getPathName()));
+                final Tlvs tlvs = buildTlvs(tunnel, plspId.getValue(), Optional.<List<Subobject>>absent());
                 session.sendReport(createPcRtpMessage(
-                        new LspBuilder(request.getLsp()).setSync(true).setOperational(OperationalStatus.Up).setDelegate(true).setTlvs(tlvs).build(),
-                        Optional.of(createSrp(srpId)), tunnel.getLspState()));
+                    new LspBuilder(request.getLsp()).setSync(true).setOperational(OperationalStatus.Up).setDelegate(true).setTlvs(tlvs).build(),
+                    Optional.of(createSrp(srpId)), tunnel.getLspState()));
             } else {
                 session.sendError(MsgBuilderUtil.createErrorMsg(PCEPErrors.LSP_NOT_PCE_INITIATED, srpId));
             }
@@ -208,9 +160,27 @@ public class PCCTunnelManagerImpl implements PccTunnelManager {
     }
 
     @Override
-    public synchronized void onSessionDown(final PccSession session) {
-        for (final Entry<PlspId, Tunnel> entry : this.tunnels.entrySet()) {
-            final Tunnel tunnel = entry.getValue();
+    public synchronized void onSessionUp(final PCCSession session) {
+        this.syncOptimization = new PCCSyncOptimization(session);
+        lazyTunnelInicialization();
+
+        //first session - delegate all PCC's LSPs only when reporting at startup
+        if (!this.sessions.containsKey(session.getId()) && session.getId() == 0) {
+            for (final PlspId plspId : this.tunnels.keySet()) {
+                setDelegation(plspId, session);
+            }
+        }
+        this.sessions.put(session.getId(), session);
+
+        if (!this.syncOptimization.isTriggeredInitSyncEnabled()) {
+            lspReport(session);
+        }
+    }
+
+    @Override
+    public synchronized void onSessionDown(final PCCSession session) {
+        for (final Entry<PlspId, PCCTunnel> entry : this.tunnels.entrySet()) {
+            final PCCTunnel tunnel = entry.getValue();
             final PlspId plspId = entry.getKey();
             //deal with delegations
             if (hasDelegation(tunnel, session)) {
@@ -220,28 +190,26 @@ public class PCCTunnelManagerImpl implements PccTunnelManager {
         }
     }
 
-    @Override
-    public void addTunnel(final Requests request, final PccSession session) {
+    protected void addTunnel(final Requests request, final PCCSession session) {
         final PlspId plspId = new PlspId(this.plspIDsCounter.incrementAndGet());
-        final Tunnel tunnel = new Tunnel(request.getLsp().getTlvs().getSymbolicPathName().getPathName().getValue(),
-                session.getId(), LspType.PCE_LSP, reqToRptPath(request));
+        final PCCTunnel tunnel = new PCCTunnel(request.getLsp().getTlvs().getSymbolicPathName().getPathName().getValue(),
+            session.getId(), LspType.PCE_LSP, reqToRptPath(request));
         sendToAll(tunnel, plspId, request.getEro().getSubobject(), createSrp(request.getSrp().getOperationId().getValue()),
-                tunnel.getLspState(), new LspBuilder(request.getLsp()).addAugmentation(Lsp1.class, new Lsp1Builder().setCreate(true).build()).build());
+            tunnel.getLspState(), new LspBuilder(request.getLsp()).addAugmentation(Lsp1.class, new Lsp1Builder().setCreate(true).build()).build());
         this.tunnels.put(plspId, tunnel);
     }
 
-    @Override
-    public void removeTunnel(final Requests request, final PccSession session) {
+    protected void removeTunnel(final Requests request, final PCCSession session) {
         final PlspId plspId = request.getLsp().getPlspId();
-        final Tunnel tunnel = this.tunnels.get(plspId);
+        final PCCTunnel tunnel = this.tunnels.get(plspId);
         final long srpId = request.getSrp().getOperationId().getValue();
         if (tunnel != null) {
             if (tunnel.getType() == LspType.PCE_LSP) {
                 if (hasDelegation(tunnel, session)) {
                     this.tunnels.remove(plspId);
                     sendToAll(tunnel, plspId, tunnel.getLspState().getEro().getSubobject(),
-                            new SrpBuilder(request.getSrp()).addAugmentation(Srp1.class, new Srp1Builder().setRemove(true).build()).build(),
-                            reqToRptPath(request), request.getLsp());
+                        new SrpBuilder(request.getSrp()).addAugmentation(Srp1.class, new Srp1Builder().setRemove(true).build()).build(),
+                        reqToRptPath(request), request.getLsp());
                 } else {
                     session.sendError(MsgBuilderUtil.createErrorMsg(PCEPErrors.UPDATE_REQ_FOR_NON_LSP, srpId));
                 }
@@ -253,26 +221,187 @@ public class PCCTunnelManagerImpl implements PccTunnelManager {
         }
     }
 
-    private void sendToAll(final Tunnel tunnel, final PlspId plspId, final List<Subobject> subobjects, final Srp srp, final Path path, final Lsp lsp) {
-        for (final PccSession session : this.sessions.values()) {
+    @Override
+    public void onMessagePcupd(@Nonnull final Updates update, @Nonnull final PCCSession session) {
+        final Lsp lsp = update.getLsp();
+        if (isInitialSyncTriggered(lsp)) {
+            lspReport(session);
+            if (this.timerHandler.isPresent()) {
+                this.timerHandler.get().createDisconnectTask();
+            }
+        } else if (isReSyncTriggered(lsp)) {
+            handledDbTriggeredResync(update, session);
+        } else if (lsp.isDelegate() != null && lsp.isDelegate()) {
+            //regular LSP update
+            reportToAll(update, session);
+        } else {
+            //returning LSP delegation
+            returnDelegation(update, session);
+        }
+    }
+
+    @Override
+    public void onMessagePcInitiate(@Nonnull final Requests request, @Nonnull final PCCSession session) {
+        if (request.getSrp().getAugmentation(Srp1.class) != null && request.getSrp().getAugmentation(Srp1.class).isRemove()) {
+            //remove LSP
+            removeTunnel(request, session);
+        } else if (request.getLsp().isDelegate() != null && request.getLsp().isDelegate() && request.getEndpointsObj() == null) {
+            //take LSP delegation
+            takeDelegation(request, session);
+        } else {
+            //create LSP
+            addTunnel(request, session);
+        }
+    }
+
+    private Tlvs buildTlvs(final PCCTunnel tunnel, final Long plspId, Optional<List<Subobject>> subobjectsList) {
+        final List<Subobject> subObject = subobjectsList.isPresent() ? subobjectsList.get() : tunnel.getLspState().getEro().getSubobject();
+        final String destinationAddress = getDestinationAddress(subObject, this.address);
+
+        return createLspTlvs(plspId, true, destinationAddress, this.address, this.address, Optional.of(tunnel.getPathName()),
+            this.syncOptimization.incrementLspDBVersion());
+    }
+
+    private void lazyTunnelInicialization() {
+        if (this.tunnels.isEmpty()) {
+            final BigInteger dbV = this.syncOptimization.getLocalLspDbVersionValue();
+            if (this.syncOptimization.isSyncAvoidanceEnabled() && !(dbV != null && dbV.equals(BigInteger.ONE))) {
+                this.tunnels.putAll(PCCTunnelBuilder.createTunnels(this.address, dbV.intValue()));
+            } else {
+                this.tunnels.putAll(PCCTunnelBuilder.createTunnels(this.address, this.lspsCount));
+            }
+        }
+    }
+
+    private boolean isReSyncTriggered(final Lsp lsp) {
+        return this.syncOptimization.isTriggeredReSyncEnabled() && lsp.isSync();
+    }
+
+    private boolean isInitialSyncTriggered(final Lsp lsp) {
+        return lsp.getPlspId().getValue() == 0 && lsp.isSync() && this.syncOptimization.isTriggeredInitSyncEnabled();
+    }
+
+    private void handledDbTriggeredResync(final Updates update, final PCCSession session) {
+        this.syncOptimization.setResynchronizingState(Boolean.TRUE);
+        final SrpIdNumber operationId = update.getSrp().getOperationId();
+        if (update.getLsp().getPlspId().getValue() == 0) {
+            reportAllKnownLsp(Optional.of(operationId), session);
+        } else {
+            reportLsp(update.getLsp().getPlspId(), operationId, session);
+        }
+        sendEndOfSynchronization(session, Optional.of(operationId));
+        this.syncOptimization.setResynchronizingState(Boolean.FALSE);
+    }
+
+    private void lspReport(final PCCSession session) {
+        if (!this.tunnels.isEmpty()) {
+            if (!this.syncOptimization.isSyncAvoidanceEnabled()) {
+                reportAllKnownLsp(session);
+                sendEndOfSynchronization(session);
+            } else if (!this.syncOptimization.doesLspDbMatch()) {
+                if (this.syncOptimization.isDeltaSyncEnabled()) {
+                    reportMissedLsp(session);
+                    sendEndOfSynchronization(session);
+                } else {
+                    reportAllKnownLsp(session);
+                    sendEndOfSynchronization(session);
+                }
+            }
+        }
+    }
+
+    /**
+     * Reports Missed Lsp when DbVersion doesnt match
+     *
+     * @param session
+     */
+    private void reportMissedLsp(final PCCSession session) {
+        for (long missedLsp = this.syncOptimization.getRemoteLspDbVersionValue().longValue() + 1;
+             missedLsp <= this.syncOptimization.getLocalLspDbVersionValue().longValue(); missedLsp++) {
+            final PlspId plspId = new PlspId(missedLsp);
+            final PCCTunnel tunnel = this.tunnels.get(plspId);
+            createLspAndSendReport(missedLsp, tunnel, session, Optional.<Boolean>absent(), NO_SRP);
+        }
+    }
+
+    private void createLspAndSendReport(final long plspId, final PCCTunnel tunnel, final PCCSession session, Optional<Boolean> isSync, final Optional<Srp> srp) {
+        final boolean delegation = hasDelegation(tunnel, session);
+        if (delegation) {
+            tunnel.cancelTimeouts();
+        }
+        final String destinationAddress = getDestinationAddress(tunnel.getLspState().getEro().getSubobject(), this.address);
+        final Tlvs tlvs = createLspTlvs(plspId, true, destinationAddress, this.address, this.address, Optional.of(tunnel.getPathName()),
+            this.syncOptimization.incrementLspDBVersion());
+
+        final boolean sync = isSync.isPresent() ? isSync.get() : this.syncOptimization.isSyncNeedIt();
+        Lsp lsp = createLsp(plspId, sync, Optional.fromNullable(tlvs), delegation, false);
+        final Pcrpt pcrtp = createPcRtpMessage(lsp, srp, tunnel.getLspState());
+        session.sendReport(pcrtp);
+    }
+
+    private void sendEndOfSynchronization(final PCCSession session) {
+        sendEndOfSynchronization(session, Optional.<SrpIdNumber>absent());
+    }
+
+    private void sendEndOfSynchronization(final PCCSession session, final Optional<SrpIdNumber> operationId) {
+        Srp srp = null;
+        if (operationId.isPresent()) {
+            srp = new SrpBuilder().setOperationId(operationId.get()).build();
+        }
+        Optional<Tlvs> tlv = Optional.absent();
+        if (this.syncOptimization.isSyncAvoidanceEnabled()) {
+            tlv = createLspTlvsEndofSync(this.syncOptimization.incrementLspDBVersion().get());
+        }
+        final Pcrpt pcrtp = createPcRtpMessage(createLsp(0, false, tlv, true, false), Optional.fromNullable(srp), createPath(Collections
+            .<Subobject>emptyList()));
+        session.sendReport(pcrtp);
+    }
+
+    private void reportAllKnownLsp(final PCCSession session) {
+        reportAllKnownLsp(Optional.<SrpIdNumber>absent(), session);
+    }
+
+    private void reportAllKnownLsp(final Optional<SrpIdNumber> operationId, final PCCSession session) {
+        Srp srp = null;
+        if (operationId.isPresent()) {
+            srp = new SrpBuilder().setOperationId(operationId.get()).build();
+        }
+
+        for (final Entry<PlspId, PCCTunnel> entry : this.tunnels.entrySet()) {
+            final PCCTunnel tunnel = entry.getValue();
+            long plspId = entry.getKey().getValue();
+            createLspAndSendReport(plspId, tunnel, session, Optional.<Boolean>absent(), Optional.fromNullable(srp));
+        }
+    }
+
+    private void reportLsp(final PlspId plspId, final SrpIdNumber operationId, final PCCSession session) {
+        final PCCTunnel tunnel = this.tunnels.get(plspId);
+        if (tunnel == null) {
+            return;
+        }
+        final Srp srp = new SrpBuilder().setOperationId(operationId).build();
+        createLspAndSendReport(plspId.getValue(), tunnel, session, Optional.of(Boolean.TRUE), Optional.of(srp));
+    }
+
+    private void sendToAll(final PCCTunnel tunnel, final PlspId plspId, final List<Subobject> subobjects, final Srp srp, final Path path, final Lsp lsp) {
+        for (final PCCSession session : this.sessions.values()) {
             final boolean isDelegated = hasDelegation(tunnel, session);
-            final Tlvs tlvs = createLspTlvs(plspId.getValue(), true,
-                    getDestinationAddress(subobjects, this.address), this.address,
-                    this.address, Optional.of(tunnel.getPathName()));
+            final Tlvs tlvs = buildTlvs(tunnel, plspId.getValue(), Optional.of(subobjects));
+
             final Pcrpt pcRpt = createPcRtpMessage(
-                    new LspBuilder(lsp)
-                        .setPlspId(plspId)
-                        .setOperational(OperationalStatus.Up)
-                        .setDelegate(isDelegated)
-                        .setSync(true)
-                        .addAugmentation(Lsp1.class, new Lsp1Builder().setCreate(tunnel.getType() == LspType.PCE_LSP ? true : false).build())
-                        .setTlvs(tlvs).build(),
-                    Optional.fromNullable(srp), path);
+                new LspBuilder(lsp)
+                    .setPlspId(plspId)
+                    .setOperational(OperationalStatus.Up)
+                    .setDelegate(isDelegated)
+                    .setSync(true)
+                    .addAugmentation(Lsp1.class, new Lsp1Builder().setCreate(tunnel.getType() == LspType.PCE_LSP).build())
+                    .setTlvs(tlvs).build(),
+                Optional.fromNullable(srp), path);
             session.sendReport(pcRpt);
         }
     }
 
-    private void startStateTimeout(final Tunnel tunnel, final PlspId plspId) {
+    private void startStateTimeout(final PCCTunnel tunnel, final PlspId plspId) {
         if (this.stateTimeout > -1) {
             final Timeout newStateTimeout = this.timer.newTimeout(new TimerTask() {
                 @Override
@@ -281,7 +410,7 @@ public class PCCTunnelManagerImpl implements PccTunnelManager {
                         PCCTunnelManagerImpl.this.tunnels.remove(plspId);
                         //report tunnel removal to all
                         sendToAll(tunnel, plspId, Collections.<Subobject>emptyList(), createSrp(0), new PathBuilder().build(),
-                                createLsp(plspId.getValue(), false, Optional.<Tlvs>absent(), false, true));
+                            createLsp(plspId.getValue(), false, Optional.<Tlvs>absent(), false, true));
                     }
                 }
             }, this.stateTimeout, TimeUnit.SECONDS);
@@ -289,7 +418,7 @@ public class PCCTunnelManagerImpl implements PccTunnelManager {
         }
     }
 
-    private void startRedelegationTimer(final Tunnel tunnel, final PlspId plspId, final PccSession session) {
+    private void startRedelegationTimer(final PCCTunnel tunnel, final PlspId plspId, final PCCSession session) {
         final Timeout newRedelegationTimeout = this.timer.newTimeout(new TimerTask() {
             @Override
             public void run(final Timeout timeout) throws Exception {
@@ -302,15 +431,14 @@ public class PCCTunnelManagerImpl implements PccTunnelManager {
                     if (index == PCCTunnelManagerImpl.this.sessions.size()) {
                         index = 0;
                     }
-                    final PccSession nextSession = PCCTunnelManagerImpl.this.sessions.get(index);
+                    final PCCSession nextSession = PCCTunnelManagerImpl.this.sessions.get(index);
                     if (nextSession != null) {
                         tunnel.cancelTimeouts();
-                        final Tlvs tlvs = createLspTlvs(plspId.getValue(), true,
-                                getDestinationAddress(tunnel.getLspState().getEro().getSubobject(), PCCTunnelManagerImpl.this.address),
-                                PCCTunnelManagerImpl.this.address, PCCTunnelManagerImpl.this.address, Optional.of(tunnel.getPathName()));
+                        final Tlvs tlvs = buildTlvs(tunnel, plspId.getValue(), Optional.<List<Subobject>>absent());
+
                         nextSession.sendReport(createPcRtpMessage(
-                                createLsp(plspId.getValue(), true, Optional.<Tlvs> fromNullable(tlvs), true, false), NO_SRP,
-                                tunnel.getLspState()));
+                            createLsp(plspId.getValue(), true, Optional.fromNullable(tlvs), true, false), NO_SRP,
+                            tunnel.getLspState()));
                         tunnel.setDelegationHolder(nextSession.getId());
                         break;
                     }
@@ -320,102 +448,29 @@ public class PCCTunnelManagerImpl implements PccTunnelManager {
         tunnel.setRedelegationTimeout(newRedelegationTimeout);
     }
 
-    private void setDelegation(final PlspId plspId, final PccSession session) {
-        final Tunnel tunnel = this.tunnels.get(plspId);
+    private void setDelegation(final PlspId plspId, final PCCSession session) {
+        final PCCTunnel tunnel = this.tunnels.get(plspId);
         final int sessionId;
         if (session != null) {
             sessionId = session.getId();
         } else {
-            sessionId = PCC_DELEGATION;
+            sessionId = PCCTunnelBuilder.PCC_DELEGATION;
         }
         tunnel.setDelegationHolder(sessionId);
     }
 
-    private static boolean hasDelegation(final Tunnel tunnel, final PccSession session) {
-        return tunnel.getDelegationHolder() == session.getId();
-    }
-
-    private static final class Tunnel {
-        private final byte[] pathName;
-        private int delegationHolder;
-        private final LspType type;
-        private Path lspState;
-        private Timeout redelegationTimeout;
-        private Timeout stateTimeout;
-
-        public Tunnel(final byte[] pathName, final int delegationHolder, final LspType type, final Path lspState) {
-            if (pathName != null) {
-                this.pathName = pathName.clone();
-            } else {
-                this.pathName = null;
-            }
-            this.delegationHolder = delegationHolder;
-            this.type = type;
-            this.lspState = lspState;
-        }
-
-        public byte[] getPathName() {
-            return this.pathName;
-        }
-
-        public int getDelegationHolder() {
-            return this.delegationHolder;
-        }
-
-        public LspType getType() {
-            return this.type;
-        }
-
-        public Path getLspState() {
-            return this.lspState;
-        }
-
-        public void setRedelegationTimeout(final Timeout redelegationTimeout) {
-            this.redelegationTimeout = redelegationTimeout;
-        }
-
-        public void setStateTimeout(final Timeout stateTimeout) {
-            this.stateTimeout = stateTimeout;
-        }
-
-        public void cancelTimeouts() {
-            if (this.redelegationTimeout != null) {
-                this.redelegationTimeout.cancel();
-            }
-            if (this.stateTimeout != null) {
-                this.stateTimeout.cancel();
-            }
-        }
-
-        public void setDelegationHolder(final int delegationHolder) {
-            this.delegationHolder = delegationHolder;
-        }
-
-        public void setLspState(final Path lspState) {
-            this.lspState = lspState;
-        }
-
-    }
-
-    enum LspType {
-        PCE_LSP, PCC_LSP
+    private static boolean hasDelegation(final PCCTunnel tunnel, final PCCSession session) {
+        final int sessionId = session.getId();
+        final int delegationHolder = tunnel.getDelegationHolder();
+        return delegationHolder == sessionId;
     }
 
     private static String getDestinationAddress(final List<Subobject> subobjects, final String defaultAddress) {
         if (subobjects != null && !subobjects.isEmpty()) {
             final String prefix = ((IpPrefixCase) subobjects.get(subobjects.size() - 1).getSubobjectType())
-                    .getIpPrefix().getIpPrefix().getIpv4Prefix().getValue();
+                .getIpPrefix().getIpPrefix().getIpv4Prefix().getValue();
             return prefix.substring(0, prefix.indexOf('/'));
         }
         return defaultAddress;
     }
-
-    private static Subobject getDefaultEROEndpointHop() {
-        final SubobjectBuilder builder = new SubobjectBuilder();
-        builder.setLoose(false);
-        builder.setSubobjectType(new IpPrefixCaseBuilder().setIpPrefix(new IpPrefixBuilder().setIpPrefix(
-                new IpPrefix(new Ipv4Prefix(ENDPOINT_PREFIX))).build()).build());
-        return builder.build();
-    }
-
 }
diff --git a/pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/PCCsBuilder.java b/pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/PCCsBuilder.java
new file mode 100644 (file)
index 0000000..d5ecbe1
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2015 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 com.google.common.base.Strings.isNullOrEmpty;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+import com.google.common.net.InetAddresses;
+import io.netty.util.HashedWheelTimer;
+import io.netty.util.Timer;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.protocol.pcep.PCEPCapability;
+import org.opendaylight.protocol.pcep.PCEPSessionListener;
+import org.opendaylight.protocol.pcep.PCEPSessionListenerFactory;
+import org.opendaylight.protocol.pcep.PCEPSessionNegotiatorFactory;
+import org.opendaylight.protocol.pcep.ietf.initiated00.CrabbeInitiatedActivator;
+import org.opendaylight.protocol.pcep.ietf.stateful07.StatefulActivator;
+import org.opendaylight.protocol.pcep.impl.BasePCEPSessionProposalFactory;
+import org.opendaylight.protocol.pcep.impl.DefaultPCEPSessionNegotiatorFactory;
+import org.opendaylight.protocol.pcep.impl.PCEPSessionImpl;
+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.PCCSessionListener;
+import org.opendaylight.protocol.pcep.spi.PCEPExtensionProviderContext;
+import org.opendaylight.protocol.pcep.spi.pojo.ServiceLoaderPCEPExtensionProviderContext;
+import org.opendaylight.protocol.pcep.sync.optimizations.SyncOptimizationsActivator;
+import org.opendaylight.tcpmd5.api.KeyMapping;
+
+final class PCCsBuilder {
+    private final int lsps;
+    private final boolean pcError;
+    private final int pccCount;
+    private final InetSocketAddress localAddress;
+    private final List<InetSocketAddress> remoteAddress;
+    private final short keepAlive;
+    private final short deadTimer;
+    private final String password;
+    private final long reconnectTime;
+    private final int redelegationTimeout;
+    private final int stateTimeout;
+    private final PCEPCapability pcepCapabilities;
+    private final Optional<BigInteger> syncOptDBVersion;
+    private PCCDispatcherImpl pccDispatcher;
+    private Timer timer = new HashedWheelTimer();
+
+    public PCCsBuilder(final int lsps, final boolean pcError, final int pccCount, @Nonnull final InetSocketAddress localAddress,
+                       @Nonnull final List<InetSocketAddress> remoteAddress, final short keepAlive, final short deadTimer, @Nonnull final String password,
+                       final long reconnectTime, final int redelegationTimeout, final int stateTimeout, final Optional<BigInteger> syncOptDBVersion,
+                       @Nonnull final PCEPCapability pcepCapabilities) {
+        this.lsps = lsps;
+        this.pcError = pcError;
+        this.pccCount = pccCount;
+        this.localAddress = localAddress;
+        this.remoteAddress = remoteAddress;
+        this.keepAlive = keepAlive;
+        this.deadTimer = deadTimer;
+        this.password = password;
+        this.reconnectTime = reconnectTime;
+        this.redelegationTimeout = redelegationTimeout;
+        this.stateTimeout = stateTimeout;
+        this.syncOptDBVersion = syncOptDBVersion;
+        this.pcepCapabilities = pcepCapabilities;
+        startActivators();
+    }
+
+    void createPCCs(final BigInteger initialDBVersion, final Optional<TimerHandler> timerHandler) throws InterruptedException, ExecutionException {
+        InetAddress currentAddress = this.localAddress.getAddress();
+        this.pccDispatcher = new PCCDispatcherImpl(ServiceLoaderPCEPExtensionProviderContext.getSingletonInstance().getMessageHandlerRegistry());
+        if(timerHandler.isPresent()) {
+            timerHandler.get().setPCCDispatcher(this.pccDispatcher);
+        }
+        for (int i = 0; i < this.pccCount; i++) {
+            final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(this.lsps, currentAddress, this.redelegationTimeout, this.stateTimeout,
+                this.timer, timerHandler);
+            createPCC(new InetSocketAddress(currentAddress, localAddress.getPort()), tunnelManager, initialDBVersion);
+            currentAddress = InetAddresses.increment(currentAddress);
+        }
+    }
+
+    private void createPCC(@Nonnull final InetSocketAddress localAddress, @Nonnull final PCCTunnelManager tunnelManager,
+                           final BigInteger initialDBVersion) throws InterruptedException, ExecutionException {
+
+        final PCEPSessionNegotiatorFactory<PCEPSessionImpl> snf = getSessionNegotiatorFactory();
+        for (final InetSocketAddress pceAddress : this.remoteAddress) {
+            this.pccDispatcher.createClient(pceAddress, this.reconnectTime,
+                new PCEPSessionListenerFactory() {
+                    @Override
+                    public PCEPSessionListener getSessionListener() {
+                        return new PCCSessionListener(remoteAddress.indexOf(pceAddress), tunnelManager, pcError);
+                    }
+                }, snf, getKeyMapping(pceAddress.getAddress(), password), localAddress, initialDBVersion);
+        }
+    }
+
+    private PCEPSessionNegotiatorFactory<PCEPSessionImpl> getSessionNegotiatorFactory() {
+        final List<PCEPCapability> capabilities = Lists.newArrayList(this.pcepCapabilities);
+        return new DefaultPCEPSessionNegotiatorFactory(new BasePCEPSessionProposalFactory(this.deadTimer, this.keepAlive, capabilities), 0);
+    }
+
+    private static KeyMapping getKeyMapping(@Nonnull final InetAddress inetAddress, @Nullable final String password) {
+        if (!isNullOrEmpty(password)) {
+            final KeyMapping keyMapping = new KeyMapping();
+            keyMapping.put(inetAddress, password.getBytes(Charsets.US_ASCII));
+            return keyMapping;
+        }
+        return null;
+    }
+
+    private static void startActivators() {
+        final PCCActivator pccActivator = new PCCActivator();
+        final StatefulActivator stateful = new StatefulActivator();
+        final SyncOptimizationsActivator optimizationsActivator = new SyncOptimizationsActivator();
+        final CrabbeInitiatedActivator activator = new CrabbeInitiatedActivator();
+        final PCEPExtensionProviderContext ctx = ServiceLoaderPCEPExtensionProviderContext.getSingletonInstance();
+        pccActivator.start(ctx);
+        stateful.start(ctx);
+        optimizationsActivator.start(ctx);
+        activator.start(ctx);
+    }
+}
diff --git a/pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/TimerHandler.java b/pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/TimerHandler.java
new file mode 100644 (file)
index 0000000..11d79b5
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2015 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.Optional;
+import io.netty.util.HashedWheelTimer;
+import io.netty.util.Timeout;
+import io.netty.util.Timer;
+import io.netty.util.TimerTask;
+import java.math.BigInteger;
+import java.util.concurrent.TimeUnit;
+import org.opendaylight.protocol.pcep.pcc.mock.protocol.PCCDispatcherImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TimerHandler {
+    private static final Logger LOG = LoggerFactory.getLogger(TimerHandler.class);
+    private final int disconnectAfter;
+    private final Timer timer = new HashedWheelTimer();
+    private PCCDispatcherImpl pccDispatcher;
+    private final int reconnectAfter;
+    private final Optional<BigInteger> syncOptDBVersion;
+    private final PCCsBuilder pcCsBuilder;
+    private boolean reconnectActive = false;
+
+    public TimerHandler(final PCCsBuilder pcCsBuilder, final Optional<BigInteger> syncOptDBVersion, final int disconnectAfter, final int reconnectAfter) {
+        this.pcCsBuilder = pcCsBuilder;
+        this.syncOptDBVersion = syncOptDBVersion;
+        this.disconnectAfter = disconnectAfter;
+        this.reconnectAfter = reconnectAfter;
+    }
+
+    final class DisconnectTask implements TimerTask {
+        @Override
+        public void run(final Timeout timeout) throws Exception {
+            LOG.debug("Disconnects PCCs, reconnect after {} seconds", reconnectAfter);
+            pccDispatcher.close();
+            if (reconnectAfter > 0) {
+                timer.newTimeout(new ReconnectTask(), reconnectAfter, TimeUnit.SECONDS);
+            }
+        }
+    }
+
+    final class ReconnectTask implements TimerTask {
+        @Override
+        public void run(final Timeout timeout) throws Exception {
+            LOG.debug("Reconnecting PCCs}");
+            pcCsBuilder.createPCCs(syncOptDBVersion.isPresent() ? syncOptDBVersion.get() : BigInteger.ONE, Optional.<TimerHandler>absent());
+        }
+    }
+
+    protected void createDisconnectTask() {
+        if (this.disconnectAfter > 0 && !reconnectActive && syncOptDBVersion.isPresent()) {
+            timer.newTimeout(new DisconnectTask(), this.disconnectAfter, TimeUnit.SECONDS);
+            reconnectActive = true;
+        }
+    }
+
+    public void setPCCDispatcher(final PCCDispatcherImpl pccDispatcher) {
+        this.pccDispatcher = pccDispatcher;
+    }
+}
diff --git a/pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/api/LspType.java b/pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/api/LspType.java
new file mode 100644 (file)
index 0000000..db5bf7c
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2015 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.api;
+
+public enum LspType {
+    PCE_LSP, PCC_LSP;
+}
similarity index 63%
rename from pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/api/PccDispatcher.java
rename to pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/api/PCCDispatcher.java
index 263b21e4dfb0fe9e0234c366fd97be5d4de16994..43526a84d19c7fc2cb598650162f346a4732f632 100644 (file)
@@ -9,16 +9,22 @@
 package org.opendaylight.protocol.pcep.pcc.mock.api;
 
 import io.netty.util.concurrent.Future;
+import java.math.BigInteger;
 import java.net.InetSocketAddress;
 import org.opendaylight.protocol.pcep.PCEPSession;
 import org.opendaylight.protocol.pcep.PCEPSessionListenerFactory;
 import org.opendaylight.protocol.pcep.PCEPSessionNegotiatorFactory;
 import org.opendaylight.tcpmd5.api.KeyMapping;
 
-public interface PccDispatcher {
+public interface PCCDispatcher {
 
     Future<PCEPSession> createClient(final InetSocketAddress remoteAddress,
             final long reconnectTime, final PCEPSessionListenerFactory listenerFactory,
             final PCEPSessionNegotiatorFactory<? extends PCEPSession> negotiatorFactory, final KeyMapping keys,
-            final InetSocketAddress localAddress);
+            final InetSocketAddress localAddress, final BigInteger dbVersion);
+
+    Future<PCEPSession> createClient(final InetSocketAddress remoteAddress,
+                                     final long reconnectTime, final PCEPSessionListenerFactory listenerFactory,
+                                     final PCEPSessionNegotiatorFactory<? extends PCEPSession> negotiatorFactory, final KeyMapping keys,
+                                     final InetSocketAddress localAddress);
 }
similarity index 76%
rename from pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/api/PccSession.java
rename to pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/api/PCCSession.java
index 9f0562ec0548bdb1b4e8895f2aad0981d19f6797..7f8241b73035b3892f284ee4e2264dfbfcfa3592 100644 (file)
@@ -10,8 +10,9 @@ package org.opendaylight.protocol.pcep.pcc.mock.api;
 
 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.message.rev131007.Pcerr;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.open.Tlvs;
 
-public interface PccSession {
+public interface PCCSession {
 
     void sendReport(Pcrpt reportMessage);
 
@@ -19,4 +20,7 @@ public interface PccSession {
 
     int getId();
 
+    Tlvs getRemoteTlvs();
+
+    Tlvs localSessionCharacteristics();
 }
similarity index 60%
rename from pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/api/PccTunnelManager.java
rename to pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/api/PCCTunnelManager.java
index e46d726bc41160c1970aa5bfd1b4aacf02e80cdc..806ff5d195d6cbb7463b84e324f235df1d978a86 100644 (file)
@@ -8,23 +8,17 @@
 
 package org.opendaylight.protocol.pcep.pcc.mock.api;
 
+import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.pcinitiate.message.pcinitiate.message.Requests;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcupd.message.pcupd.message.Updates;
 
-public interface PccTunnelManager {
+public interface PCCTunnelManager {
 
-    void reportToAll(Updates updates, PccSession session);
+    void onSessionUp(PCCSession session);
 
-    void returnDelegation(Updates updates, PccSession session);
+    void onSessionDown(PCCSession session);
 
-    void takeDelegation(Requests request, PccSession session);
-
-    void onSessionUp(PccSession session);
-
-    void onSessionDown(PccSession session);
-
-    void addTunnel(Requests request, PccSession session);
-
-    void removeTunnel(Requests request, PccSession session);
+    void onMessagePcupd(@Nonnull Updates update, @Nonnull PCCSession session);
 
+    void onMessagePcInitiate(@Nonnull Requests request, @Nonnull PCCSession session);
 }
similarity index 82%
rename from pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/PCCDispatcherImpl.java
rename to pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/protocol/PCCDispatcherImpl.java
index 5e1f10e84975cb290f846f596e9afa318712f39b..a2737832504e5f72679025822b39f6d35954b511 100644 (file)
@@ -6,7 +6,7 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.protocol.pcep.pcc.mock;
+package org.opendaylight.protocol.pcep.pcc.mock.protocol;
 
 import io.netty.bootstrap.Bootstrap;
 import io.netty.channel.ChannelHandlerContext;
@@ -18,8 +18,11 @@ import io.netty.channel.socket.SocketChannel;
 import io.netty.channel.socket.nio.NioSocketChannel;
 import io.netty.util.concurrent.Future;
 import io.netty.util.concurrent.GlobalEventExecutor;
+import java.math.BigInteger;
 import java.net.InetSocketAddress;
 import java.util.concurrent.ExecutionException;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import org.opendaylight.protocol.framework.NeverReconnectStrategy;
 import org.opendaylight.protocol.framework.ReconnectStrategy;
 import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
@@ -28,7 +31,7 @@ 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.protocol.pcep.pcc.mock.api.PCCDispatcher;
 import org.opendaylight.protocol.pcep.spi.MessageRegistry;
 import org.opendaylight.tcpmd5.api.DummyKeyAccessFactory;
 import org.opendaylight.tcpmd5.api.KeyAccessFactory;
@@ -41,7 +44,7 @@ import org.opendaylight.tcpmd5.netty.MD5NioSocketChannelFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public final class PCCDispatcherImpl implements PccDispatcher, AutoCloseable {
+public final class PCCDispatcherImpl implements PCCDispatcher, AutoCloseable {
 
     private static final Logger LOG = LoggerFactory.getLogger(PCCDispatcherImpl.class);
 
@@ -51,7 +54,7 @@ public final class PCCDispatcherImpl implements PccDispatcher, AutoCloseable {
     private final MD5ChannelFactory<?> cf;
     private final NioEventLoopGroup workerGroup;
 
-    public PCCDispatcherImpl(final MessageRegistry registry) {
+    public PCCDispatcherImpl(@Nonnull final MessageRegistry registry) {
         this.workerGroup = new NioEventLoopGroup();
         this.factory = new PCEPHandlerFactory(registry);
         this.cf = new MD5NioSocketChannelFactory(DeafultKeyAccessFactory.getKeyAccessFactory());
@@ -84,9 +87,16 @@ public final class PCCDispatcherImpl implements PccDispatcher, AutoCloseable {
     }
 
     @Override
-    public Future<PCEPSession> createClient(
-        final InetSocketAddress remoteAddress, final long reconnectTime, final PCEPSessionListenerFactory listenerFactory,
-        final PCEPSessionNegotiatorFactory negotiatorFactory, final KeyMapping keys, final InetSocketAddress localAddress) {
+    public Future<PCEPSession> createClient(@Nonnull final InetSocketAddress remoteAddress, @Nonnull final long reconnectTime,
+                                            @Nonnull final PCEPSessionListenerFactory listenerFactory, @Nonnull final PCEPSessionNegotiatorFactory negotiatorFactory,
+                                            @Nonnull final KeyMapping keys, @Nullable final InetSocketAddress localAddress) {
+        return createClient(remoteAddress, reconnectTime, listenerFactory, negotiatorFactory, keys, localAddress, BigInteger.ONE);
+    }
+
+    @Override
+    public Future<PCEPSession> createClient(@Nonnull final InetSocketAddress remoteAddress, @Nonnull final long reconnectTime,
+                                            @Nonnull final PCEPSessionListenerFactory listenerFactory, @Nonnull final PCEPSessionNegotiatorFactory negotiatorFactory,
+                                            @Nonnull final KeyMapping keys, @Nullable final InetSocketAddress localAddress, @Nonnull final BigInteger dbVersion) {
         final Bootstrap b = new Bootstrap();
         b.group(this.workerGroup);
         b.localAddress(localAddress);
@@ -99,7 +109,7 @@ public final class PCCDispatcherImpl implements PccDispatcher, AutoCloseable {
             @Override
             protected void initChannel(final SocketChannel ch) throws Exception {
                 ch.pipeline().addLast(PCCDispatcherImpl.this.factory.getDecoders());
-                ch.pipeline().addLast("negotiator", negotiatorFactory.getSessionNegotiator(listenerFactory, ch, promise, null));
+                ch.pipeline().addLast("negotiator", negotiatorFactory.getSessionNegotiator(listenerFactory, ch, promise, new PCCPeerProposal(dbVersion)));
                 ch.pipeline().addLast(PCCDispatcherImpl.this.factory.getEncoders());
                 ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
                     @Override
@@ -114,7 +124,7 @@ public final class PCCDispatcherImpl implements PccDispatcher, AutoCloseable {
                         }
                         LOG.debug("Reconnecting after connection to {} was dropped", remoteAddress);
                         PCCDispatcherImpl.this.createClient(remoteAddress, reconnectTime, listenerFactory, negotiatorFactory,
-                            keys, localAddress);
+                            keys, localAddress, dbVersion);
                     }
                 });
             }
diff --git a/pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/protocol/PCCPeerProposal.java b/pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/protocol/PCCPeerProposal.java
new file mode 100644 (file)
index 0000000..bd75bee
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2015 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.protocol;
+
+import com.google.common.base.Preconditions;
+import java.math.BigInteger;
+import java.net.InetSocketAddress;
+import javax.annotation.Nonnull;
+import org.opendaylight.protocol.pcep.PCEPPeerProposal;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.sync.optimizations.rev150714.Tlvs3;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.sync.optimizations.rev150714.Tlvs3Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.sync.optimizations.rev150714.lsp.db.version.tlv.LspDbVersion;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.sync.optimizations.rev150714.lsp.db.version.tlv.LspDbVersionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.open.TlvsBuilder;
+
+public final class PCCPeerProposal implements PCEPPeerProposal {
+    private final BigInteger dbVersion;
+
+    public PCCPeerProposal(@Nonnull final BigInteger dbVersion) {
+        this.dbVersion = dbVersion;
+    }
+
+    public PCCPeerProposal() {
+        this.dbVersion = null;
+    }
+
+    @Override
+    public void setPeerSpecificProposal(@Nonnull final InetSocketAddress address, @Nonnull final TlvsBuilder openBuilder) {
+        Preconditions.checkNotNull(address);
+        final LspDbVersion LspDBV = new LspDbVersionBuilder().setLspDbVersionValue(this.dbVersion).build();
+        openBuilder.addAugmentation(Tlvs3.class, new Tlvs3Builder().setLspDbVersion(LspDBV).build());
+    }
+}
similarity index 98%
rename from pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/PCCReconnectPromise.java
rename to pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/protocol/PCCReconnectPromise.java
index 152f4e8099322ce8bfaefa21bfbb15ef5fbc29e1..f3fe2be30970b31b190b380f6ef399c3c4040948 100644 (file)
@@ -6,7 +6,7 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.protocol.pcep.pcc.mock;
+package org.opendaylight.protocol.pcep.pcc.mock.protocol;
 
 import com.google.common.base.Preconditions;
 import io.netty.bootstrap.Bootstrap;
diff --git a/pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/protocol/PCCServerPeerProposal.java b/pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/protocol/PCCServerPeerProposal.java
new file mode 100644 (file)
index 0000000..c35f8e9
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2015 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.protocol;
+
+import com.google.common.base.Preconditions;
+import java.math.BigInteger;
+import java.net.InetSocketAddress;
+import javax.annotation.Nonnull;
+import org.opendaylight.protocol.pcep.PCEPPeerProposal;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.sync.optimizations.rev150714.Tlvs3;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.sync.optimizations.rev150714.Tlvs3Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.sync.optimizations.rev150714.lsp.db.version.tlv.LspDbVersionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.open.TlvsBuilder;
+
+public class PCCServerPeerProposal implements PCEPPeerProposal {
+    private boolean isAfterReconnection;
+    private final BigInteger dbVersion;
+
+    public PCCServerPeerProposal(@Nonnull final BigInteger dbVersion) {
+        this.dbVersion = dbVersion;
+    }
+
+    @Override
+    public void setPeerSpecificProposal(@Nonnull final InetSocketAddress address, @Nonnull final TlvsBuilder openBuilder) {
+        Preconditions.checkNotNull(address);
+        final LspDbVersionBuilder LspDBV = new LspDbVersionBuilder();
+        if (isAfterReconnection) {
+            LspDBV.setLspDbVersionValue(this.dbVersion);
+        } else {
+            isAfterReconnection = true;
+        }
+        openBuilder.addAugmentation(Tlvs3.class, new Tlvs3Builder().setLspDbVersion(LspDBV.build()).build());
+    }
+}
\ No newline at end of file
similarity index 68%
rename from pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/PCCSessionListener.java
rename to pcep/pcc-mock/src/main/java/org/opendaylight/protocol/pcep/pcc/mock/protocol/PCCSessionListener.java
index b2be1fdb31a8c53f9072dd81951a470eb9c8b7c0..e304ea4c5ff98b3c94203b69d0f74b8f5bfce3d9 100644 (file)
@@ -6,37 +6,37 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.protocol.pcep.pcc.mock;
+package org.opendaylight.protocol.pcep.pcc.mock.protocol;
 
 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.pcc.mock.api.PccSession;
-import org.opendaylight.protocol.pcep.pcc.mock.api.PccTunnelManager;
+import org.opendaylight.protocol.pcep.pcc.mock.MsgBuilderUtil;
+import org.opendaylight.protocol.pcep.pcc.mock.api.PCCSession;
+import org.opendaylight.protocol.pcep.pcc.mock.api.PCCTunnelManager;
 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.Pcinitiate;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.Srp1;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.pcinitiate.message.pcinitiate.message.Requests;
 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.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.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.open.object.open.Tlvs;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class PCCSessionListener implements PCEPSessionListener, PccSession {
+public final class PCCSessionListener implements PCEPSessionListener, PCCSession {
 
     private static final Logger LOG = LoggerFactory.getLogger(PCCSessionListener.class);
 
     private final boolean errorMode;
-    private final PccTunnelManager tunnelManager;
+    private final PCCTunnelManager tunnelManager;
     private final int sessionId;
     private PCEPSession session;
 
-    public PCCSessionListener(final int sessionId, final PccTunnelManager tunnelManager, final boolean errorMode) {
+    public PCCSessionListener(final int sessionId, final PCCTunnelManager tunnelManager, final boolean errorMode) {
         this.errorMode = errorMode;
         this.tunnelManager = tunnelManager;
         this.sessionId = sessionId;
@@ -51,34 +51,10 @@ public class PCCSessionListener implements PCEPSessionListener, PccSession {
             return;
         }
         if (message instanceof Pcupd) {
-            handlePcupd((Pcupd) message);
+            final Updates upd = ((Pcupd) message).getPcupdMessage().getUpdates().get(0);
+            this.tunnelManager.onMessagePcupd(upd, this);
         } else if (message instanceof Pcinitiate) {
-            handlePcinitiate((Pcinitiate) message);
-        }
-    }
-
-    private void handlePcupd(final Pcupd message) {
-        final Updates update = message.getPcupdMessage().getUpdates().get(0);
-        if (update.getLsp().isDelegate() != null && update.getLsp().isDelegate()) {
-            //regular LSP update
-            this.tunnelManager.reportToAll(update, this);
-        } else {
-            //returning LSP delegation
-            this.tunnelManager.returnDelegation(update, this);
-        }
-    }
-
-    private void handlePcinitiate(final Pcinitiate message) {
-        final Requests request = message.getPcinitiateMessage().getRequests().get(0);
-        if (request.getSrp().getAugmentation(Srp1.class) != null && request.getSrp().getAugmentation(Srp1.class).isRemove()) {
-            //remove LSP
-            this.tunnelManager.removeTunnel(request, this);
-        } else if (request.getLsp().isDelegate() != null && request.getLsp().isDelegate() && request.getEndpointsObj() == null) {
-            //take LSP delegation
-            this.tunnelManager.takeDelegation(request, this);
-        } else {
-            //create LSP
-            this.tunnelManager.addTunnel(request, this);
+            this.tunnelManager.onMessagePcInitiate(((Pcinitiate) message).getPcinitiateMessage().getRequests().get(0), this);
         }
     }
 
@@ -120,6 +96,16 @@ public class PCCSessionListener implements PCEPSessionListener, PccSession {
         return this.sessionId;
     }
 
+    @Override
+    public Tlvs getRemoteTlvs() {
+        return this.session.getRemoteTlvs();
+    }
+
+    @Override
+    public Tlvs localSessionCharacteristics() {
+        return this.session.localSessionCharacteristics();
+    }
+
     private final Random rnd = new Random();
 
     private PCEPErrors getRandomError() {
index 450b4d35255668ee14914146481d4c1fdb5a35fd..6036d542bb27e67879f8e896fa09b4f1661d6986 100644 (file)
@@ -28,6 +28,7 @@ import org.opendaylight.protocol.pcep.PCEPSessionProposalFactory;
 import org.opendaylight.protocol.pcep.impl.BasePCEPSessionProposalFactory;
 import org.opendaylight.protocol.pcep.impl.DefaultPCEPSessionNegotiatorFactory;
 import org.opendaylight.protocol.pcep.impl.PCEPDispatcherImpl;
+import org.opendaylight.protocol.pcep.pcc.mock.protocol.PCCDispatcherImpl;
 import org.opendaylight.protocol.pcep.spi.pojo.ServiceLoaderPCEPExtensionProviderContext;
 
 public class PCCDispatcherImplTest {
@@ -85,7 +86,7 @@ public class PCCDispatcherImplTest {
 
         final TestingSessionListenerFactory slf2 = new TestingSessionListenerFactory();
         this.pcepDispatcher.createServer(this.serverAddress, slf2, null).channel();
-        Thread.sleep(2000);
+        Thread.sleep(500);
 
         final TestingSessionListener sl2 = slf2.getSessionListenerByRemoteAddress(this.clientAddress.getAddress());
         Assert.assertNotNull(sl2);
diff --git a/pcep/pcc-mock/src/test/java/org/opendaylight/protocol/pcep/pcc/mock/PCCIncrementalSyncTest.java b/pcep/pcc-mock/src/test/java/org/opendaylight/protocol/pcep/pcc/mock/PCCIncrementalSyncTest.java
new file mode 100644 (file)
index 0000000..db4e246
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2015 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.junit.Assert.assertFalse;
+
+import com.google.common.base.Optional;
+import io.netty.channel.Channel;
+import java.math.BigInteger;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import org.junit.Test;
+import org.opendaylight.protocol.pcep.PCEPCapability;
+import org.opendaylight.protocol.pcep.ietf.stateful07.PCEPStatefulCapability;
+import org.opendaylight.protocol.pcep.pcc.mock.protocol.PCCServerPeerProposal;
+
+public class PCCIncrementalSyncTest extends PCCMockCommon {
+
+    private BigInteger lsp = BigInteger.valueOf(8);
+    /**
+     * Test Incremental Synchronization
+     * Create 8 lsp, then it disconnects after 5 sec and then after 5 sec reconnects with Pcc DBVersion 10
+     * After reconnection PCE has DBVersion 10, therefore there is 9 changes missed. 9 Pcrt + 1 Pcrt-Sync
+     */
+    private final String[] mainInputIncrementalSync = new String[]{"--local-address", PCCMockTest.LOCAL_ADDRESS, "--remote-address",
+        PCCMockTest.REMOTE_ADDRESS + ":4578", "--pcc", "1", "--lsp", lsp.toString(), "--log-level", "DEBUG", "-ka", "40", "-d", "120",
+        "--reconnect", "-1", "--redelegation-timeout", "0", "--state-timeout", "-1", "--incremental-sync-procedure", "10", "5", "5"};
+
+    @Test
+    public void testSessionIncrementalSyncEstablishment() throws UnknownHostException, InterruptedException, ExecutionException {
+        final TestingSessionListenerFactory factory = new TestingSessionListenerFactory();
+        final BigInteger numberOflspAndDBv = BigInteger.valueOf(8);
+        final Channel channel = createServer(factory, socket, new PCCServerPeerProposal(numberOflspAndDBv));
+        Main.main(mainInputIncrementalSync);
+        Thread.sleep(1000);
+        final TestingSessionListener pceSessionListener = getListener(factory);
+        checkSynchronizedSession(8, pceSessionListener, numberOflspAndDBv);
+        Thread.sleep(4000);
+        assertFalse(pceSessionListener.isUp());
+        Thread.sleep(6000);
+        Thread.sleep(1000);
+        final int expetedNumberOfLspAndEndOfSync = 3;
+        final BigInteger expectedFinalDBVersion = BigInteger.valueOf(10);
+        final TestingSessionListener sessionListenerAfterReconnect = getListener(factory);
+        checkResyncSession(Optional.<Integer>absent(), expetedNumberOfLspAndEndOfSync, numberOflspAndDBv, expectedFinalDBVersion, sessionListenerAfterReconnect);
+        channel.close().get();
+    }
+
+    @Override
+    protected List<PCEPCapability> getCapabilities() {
+        final List<PCEPCapability> caps = new ArrayList<>();
+        caps.add(new PCEPStatefulCapability(true, true, true, false, false, true, true));
+        return caps;
+    }
+
+    @Override
+    protected int getPort() {
+        return 4578;
+    }
+}
diff --git a/pcep/pcc-mock/src/test/java/org/opendaylight/protocol/pcep/pcc/mock/PCCMockCommon.java b/pcep/pcc-mock/src/test/java/org/opendaylight/protocol/pcep/pcc/mock/PCCMockCommon.java
new file mode 100644 (file)
index 0000000..98a3160
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2015 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.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.base.Optional;
+import com.google.common.net.InetAddresses;
+import io.netty.channel.Channel;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.util.HashedWheelTimer;
+import io.netty.util.concurrent.Future;
+import java.math.BigInteger;
+import java.net.InetSocketAddress;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import org.junit.Before;
+import org.opendaylight.protocol.pcep.PCEPCapability;
+import org.opendaylight.protocol.pcep.PCEPDispatcher;
+import org.opendaylight.protocol.pcep.PCEPPeerProposal;
+import org.opendaylight.protocol.pcep.PCEPSession;
+import org.opendaylight.protocol.pcep.PCEPSessionListener;
+import org.opendaylight.protocol.pcep.PCEPSessionListenerFactory;
+import org.opendaylight.protocol.pcep.PCEPSessionNegotiatorFactory;
+import org.opendaylight.protocol.pcep.ietf.stateful07.StatefulActivator;
+import org.opendaylight.protocol.pcep.impl.BasePCEPSessionProposalFactory;
+import org.opendaylight.protocol.pcep.impl.DefaultPCEPSessionNegotiatorFactory;
+import org.opendaylight.protocol.pcep.impl.PCEPDispatcherImpl;
+import org.opendaylight.protocol.pcep.impl.PCEPSessionImpl;
+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.PCCSessionListener;
+import org.opendaylight.protocol.pcep.spi.PCEPExtensionProviderContext;
+import org.opendaylight.protocol.pcep.spi.pojo.ServiceLoaderPCEPExtensionProviderContext;
+import org.opendaylight.protocol.pcep.sync.optimizations.SyncOptimizationsActivator;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.sync.optimizations.rev150714.Tlvs3;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.Stateful1;
+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.Tlvs1;
+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.pcrpt.message.pcrpt.message.Reports;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
+
+public abstract class PCCMockCommon {
+    protected static final String REMOTE_ADDRESS = "127.0.1.0";
+    protected static final String LOCAL_ADDRESS = "127.0.0.1";
+    private final static short KEEP_ALIVE = 40;
+    private final static short DEAD_TIMER = 120;
+    protected final InetSocketAddress socket = new InetSocketAddress(PCCMockCommon.REMOTE_ADDRESS, getPort());
+    private PCEPDispatcher pceDispatcher;
+    private PCCDispatcherImpl pccDispatcher;
+    protected PCCSessionListener pccSessionListener;
+
+    protected abstract List<PCEPCapability> getCapabilities();
+
+    protected abstract int getPort();
+
+    @Before
+    public void setUp() {
+        final BasePCEPSessionProposalFactory proposal = new BasePCEPSessionProposalFactory(DEAD_TIMER, KEEP_ALIVE, getCapabilities());
+        final DefaultPCEPSessionNegotiatorFactory nf = new DefaultPCEPSessionNegotiatorFactory(proposal, 0);
+        this.pceDispatcher = new PCEPDispatcherImpl(ServiceLoaderPCEPExtensionProviderContext.getSingletonInstance().getMessageHandlerRegistry(),
+            nf, new NioEventLoopGroup(), new NioEventLoopGroup());
+    }
+
+    protected static TestingSessionListener checkSessionListener(final int numMessages, final Channel channel, final TestingSessionListenerFactory factory, final String localAddress) throws
+        ExecutionException, InterruptedException {
+        final TestingSessionListener sessionListener = factory.getSessionListenerByRemoteAddress(InetAddresses.forString(localAddress));
+        assertNotNull(sessionListener);
+        assertTrue(sessionListener.isUp());
+        assertEquals(numMessages, sessionListener.messages().size());
+        channel.close().get();
+        return sessionListener;
+    }
+
+    protected Channel createServer(final TestingSessionListenerFactory factory, final InetSocketAddress serverAddress2) {
+        return createServer(factory, serverAddress2, null);
+    }
+
+    protected Channel createServer(final TestingSessionListenerFactory factory, final InetSocketAddress
+        serverAddress2, final PCEPPeerProposal peerProposal) {
+        final PCEPExtensionProviderContext ctx = ServiceLoaderPCEPExtensionProviderContext.getSingletonInstance();
+        final StatefulActivator activator07 = new StatefulActivator();
+        final SyncOptimizationsActivator optimizationsActivator = new SyncOptimizationsActivator();
+        activator07.start(ctx);
+        optimizationsActivator.start(ctx);
+        return this.pceDispatcher.createServer(serverAddress2, factory, peerProposal).channel();
+    }
+
+    protected static void checkSynchronizedSession(final int numberOfLsp, final TestingSessionListener pceSessionListener, final BigInteger expectedeInitialDb) throws InterruptedException {
+        assertTrue(pceSessionListener.isUp());
+        Thread.sleep(1000);
+        //Send Open with LspDBV = 1
+        final List<Message> messages = pceSessionListener.messages();
+        int numberOfSyncMessage = 1;
+        int numberOfLspExpected = numberOfLsp;
+        if(!expectedeInitialDb.equals(BigInteger.ZERO)) {
+            checkSequequenceDBVersionSync(messages, expectedeInitialDb);
+            numberOfLspExpected += numberOfSyncMessage;
+        }
+        assertEquals(numberOfLspExpected, messages.size());
+        final PCEPSession session = pceSessionListener.getSession();
+        checkSession(session, DEAD_TIMER, KEEP_ALIVE);
+
+        assertTrue(session.getRemoteTlvs().getAugmentation(Tlvs1.class).getStateful().getAugmentation(Stateful1.class).isInitiation());
+        assertNull(session.localSessionCharacteristics().getAugmentation(Tlvs3.class).getLspDbVersion().getLspDbVersionValue());
+    }
+
+    protected static void checkResyncSession(final Optional<Integer> startAtNumberLsp, final int expectedNumberOfLsp, final BigInteger startingDBVersion,
+                                             final BigInteger expectedDBVersion, final TestingSessionListener pceSessionListener) {
+        assertTrue(pceSessionListener.isUp());
+        List<Message> messages;
+        if(startAtNumberLsp.isPresent()) {
+            messages = pceSessionListener.messages().subList(startAtNumberLsp.get(), startAtNumberLsp.get() + expectedNumberOfLsp);
+        } else {
+            messages = pceSessionListener.messages();
+        }
+        checkSequequenceDBVersionSync(messages, expectedDBVersion);
+        assertEquals(expectedNumberOfLsp, messages.size());
+        final PCEPSession session = pceSessionListener.getSession();
+
+        checkSession(session, DEAD_TIMER, KEEP_ALIVE);
+
+        assertTrue(session.getRemoteTlvs().getAugmentation(Tlvs1.class).getStateful().getAugmentation(Stateful1.class).isInitiation());
+        final BigInteger pceDBVersion = session.localSessionCharacteristics().getAugmentation(Tlvs3.class).getLspDbVersion().getLspDbVersionValue();
+        assertEquals(startingDBVersion, pceDBVersion);
+    }
+
+    protected static void checkSession(final PCEPSession session, final int expectedDeadTimer, final int expectedKeepAlive) {
+        assertNotNull(session);
+        assertEquals(expectedDeadTimer, session.getPeerPref().getDeadtimer().shortValue());
+        assertEquals(expectedKeepAlive, session.getPeerPref().getKeepalive().shortValue());
+        final Stateful1 stateful = session.getRemoteTlvs().getAugmentation(Tlvs1.class).getStateful().getAugmentation(Stateful1.class);
+        assertTrue(stateful.isInitiation());
+    }
+
+    protected static void checkSequequenceDBVersionSync(final List<Message> messages, final BigInteger expectedDbVersion) {
+        for (Message msg : messages) {
+            final List<Reports> pcrt = ((Pcrpt) msg).getPcrptMessage().getReports();
+            for (Reports report : pcrt) {
+                final Lsp lsp = report.getLsp();
+                if (lsp.getPlspId().getValue() == 0) {
+                    assertEquals(false, lsp.isSync().booleanValue());
+                } else {
+                    assertEquals(true, lsp.isSync().booleanValue());
+                }
+                final BigInteger actuaLspDBVersion = lsp.getTlvs().getAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params
+                    .xml.ns.yang.controller.pcep.sync.optimizations.rev150714.Tlvs1.class).getLspDbVersion().getLspDbVersionValue();
+                assertEquals(expectedDbVersion, actuaLspDBVersion);
+            }
+        }
+    }
+
+    protected Future<PCEPSession> createPCCSession(BigInteger DBVersion) {
+        this.pccDispatcher = new PCCDispatcherImpl(ServiceLoaderPCEPExtensionProviderContext.getSingletonInstance().getMessageHandlerRegistry());
+        final PCEPSessionNegotiatorFactory<PCEPSessionImpl> snf = getSessionNegotiatorFactory();
+        final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(3, getLocalAdress().getAddress(), 0, -1, new HashedWheelTimer(),
+            Optional.<TimerHandler>absent());
+
+        return pccDispatcher.createClient(getRemoteAdress(), -1,
+            new PCEPSessionListenerFactory() {
+                @Override
+                public PCEPSessionListener getSessionListener() {
+                    pccSessionListener = new PCCSessionListener(1, tunnelManager, false);
+                    return pccSessionListener;
+                }
+            }, snf, null, getLocalAdress(), DBVersion);
+    }
+
+    private InetSocketAddress getLocalAdress() {
+        return new InetSocketAddress(PCCMockTest.LOCAL_ADDRESS, getPort());
+    }
+
+    private InetSocketAddress getRemoteAdress() {
+        return new InetSocketAddress(PCCMockTest.REMOTE_ADDRESS, getPort());
+    }
+
+    private PCEPSessionNegotiatorFactory<PCEPSessionImpl> getSessionNegotiatorFactory() {
+        return new DefaultPCEPSessionNegotiatorFactory(new BasePCEPSessionProposalFactory(DEAD_TIMER, KEEP_ALIVE, getCapabilities()), 0);
+    }
+
+    protected TestingSessionListener getListener(final TestingSessionListenerFactory factory) {
+        return factory.getSessionListenerByRemoteAddress(InetAddresses.forString(PCCMockTest.LOCAL_ADDRESS));
+    }
+}
index faec6d6d6c2c57f6c678bfdd9ba59c0bb1fafd96..d531fe95029f4cb3b037c72952dcc6569c61a555 100644 (file)
 
 package org.opendaylight.protocol.pcep.pcc.mock;
 
-import com.google.common.net.InetAddresses;
 import io.netty.channel.Channel;
-import io.netty.channel.nio.NioEventLoopGroup;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.net.InetSocketAddress;
 import java.net.UnknownHostException;
 import java.util.Collections;
+import java.util.List;
 import java.util.concurrent.ExecutionException;
-import org.junit.Assert;
-import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.protocol.pcep.PCEPCapability;
-import org.opendaylight.protocol.pcep.PCEPDispatcher;
-import org.opendaylight.protocol.pcep.PCEPSession;
-import org.opendaylight.protocol.pcep.PCEPSessionProposalFactory;
-import org.opendaylight.protocol.pcep.impl.BasePCEPSessionProposalFactory;
-import org.opendaylight.protocol.pcep.impl.DefaultPCEPSessionNegotiatorFactory;
-import org.opendaylight.protocol.pcep.impl.PCEPDispatcherImpl;
-import org.opendaylight.protocol.pcep.spi.pojo.ServiceLoaderPCEPExtensionProviderContext;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.Stateful1;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.Tlvs1;
 
-public class PCCMockTest {
-
-    private static final short KEEP_ALIVE = 30;
-    private static final short DEAD_TIMER = 120;
-    private static final String REMOTE_ADDRESS = "127.0.1.0";
+public class PCCMockTest extends PCCMockCommon {
     private static final String REMOTE_ADDRESS2 = "127.0.2.0";
     private static final String REMOTE_ADDRESS3 = "127.0.3.0";
     private static final String REMOTE_ADDRESS4 = "127.0.4.0";
+    private static final String LOCAL_ADDRESS2 = "127.0.0.2";
     private static final InetSocketAddress SERVER_ADDRESS2 = new InetSocketAddress(REMOTE_ADDRESS2, 4189);
     private static final InetSocketAddress SERVER_ADDRESS3 = new InetSocketAddress(REMOTE_ADDRESS3, 4189);
     private static final InetSocketAddress SERVER_ADDRESS4 = new InetSocketAddress(REMOTE_ADDRESS4, 4189);
-    private static final String LOCAL_ADDRESS = "127.0.0.1";
-    private static final String LOCAL_ADDRESS2 = "127.0.0.2";
-    private static final PCEPSessionProposalFactory PROPOSAL = new BasePCEPSessionProposalFactory(DEAD_TIMER, KEEP_ALIVE,
-            Collections.<PCEPCapability>emptyList());
-
-    private PCEPDispatcher pceDispatcher;
-
-    @Before
-    public void setUp() {
-        final DefaultPCEPSessionNegotiatorFactory nf = new DefaultPCEPSessionNegotiatorFactory(
-                PROPOSAL, 0);
-        this.pceDispatcher = new PCEPDispatcherImpl(ServiceLoaderPCEPExtensionProviderContext.getSingletonInstance().getMessageHandlerRegistry(),
-                nf, new NioEventLoopGroup(), new NioEventLoopGroup());
-    }
+    private final String[] mainInput = new String[]{"--local-address", PCCMockCommon.LOCAL_ADDRESS, "--remote-address",
+        PCCMockCommon.REMOTE_ADDRESS + ":4560", "--pcc", "1", "--lsp", "3", "--log-level", "DEBUG", "-ka", "10", "-d", "40", "--reconnect", "-1",
+        "--redelegation-timeout", "0", "--state-timeout", "-1"};
 
     @Test
     public void testSessionEstablishment() throws UnknownHostException, InterruptedException, ExecutionException {
         final TestingSessionListenerFactory factory = new TestingSessionListenerFactory();
-        final Channel channel = this.pceDispatcher.createServer(new InetSocketAddress(REMOTE_ADDRESS, 4567), factory, null).channel();
-        Main.main(new String[] {"--local-address", LOCAL_ADDRESS, "--remote-address", REMOTE_ADDRESS + ":4567", "--pcc", "1", "--lsp", "3",
-            "--log-level", "DEBUG", "-ka", "10", "-d", "40", "--reconnect", "-1", "--redelegation-timeout", "0", "--state-timeout", "-1"});
+        final Channel channel = createServer(factory, this.socket);
+        Main.main(mainInput);
         Thread.sleep(1000);
-        final TestingSessionListener sessionListener = factory.getSessionListenerByRemoteAddress(InetAddresses.forString(LOCAL_ADDRESS));
-        Assert.assertTrue(sessionListener.isUp());
         //3 reported LSPs + syc
-        Assert.assertEquals(4, sessionListener.messages().size());
-        final PCEPSession session = sessionListener.getSession();
-        Assert.assertNotNull(session);
-        Assert.assertEquals(40, session.getPeerPref().getDeadtimer().shortValue());
-        Assert.assertEquals(10, session.getPeerPref().getKeepalive().shortValue());
-        Assert.assertTrue(session.getRemoteTlvs().getAugmentation(Tlvs1.class).getStateful().getAugmentation(Stateful1.class).isInitiation());
-        channel.close().get();
+        final int numMessages = 4;
+        final TestingSessionListener sessionListener = checkSessionListener(numMessages, channel, factory, PCCMockCommon.LOCAL_ADDRESS);
+        checkSession(sessionListener.getSession(), 40, 10);
     }
 
+
     @Test
     public void testMockPCCToManyPCE() throws InterruptedException, ExecutionException, UnknownHostException {
-        final DefaultPCEPSessionNegotiatorFactory nf = new DefaultPCEPSessionNegotiatorFactory(PROPOSAL, 0);
-        final PCEPDispatcher dispatcher2 = new PCEPDispatcherImpl(ServiceLoaderPCEPExtensionProviderContext.getSingletonInstance().getMessageHandlerRegistry(),
-                nf, new NioEventLoopGroup(), new NioEventLoopGroup());
-        final DefaultPCEPSessionNegotiatorFactory nf2 = new DefaultPCEPSessionNegotiatorFactory(PROPOSAL, 0);
-        final PCEPDispatcher dispatcher3 = new PCEPDispatcherImpl(ServiceLoaderPCEPExtensionProviderContext.getSingletonInstance().getMessageHandlerRegistry(),
-                nf2, new NioEventLoopGroup(), new NioEventLoopGroup());
         final TestingSessionListenerFactory factory = new TestingSessionListenerFactory();
         final TestingSessionListenerFactory factory2 = new TestingSessionListenerFactory();
         final TestingSessionListenerFactory factory3 = new TestingSessionListenerFactory();
-        final Channel channel = this.pceDispatcher.createServer(SERVER_ADDRESS2, factory, null).channel();
-        final Channel channel2 = dispatcher2.createServer(SERVER_ADDRESS3, factory2, null).channel();
-        final Channel channel3 = dispatcher3.createServer(SERVER_ADDRESS4, factory3, null).channel();
+        final Channel channel = createServer(factory, SERVER_ADDRESS2);
+        final Channel channel2 = createServer(factory2, SERVER_ADDRESS3);
+        final Channel channel3 = createServer(factory3, SERVER_ADDRESS4);
 
-        Main.main(new String[] {"--local-address", LOCAL_ADDRESS, "--remote-address", REMOTE_ADDRESS2 + "," + REMOTE_ADDRESS3 + "," + REMOTE_ADDRESS4,
-            "--pcc", "2"});
+        Main.main(new String[]{"--local-address", PCCMockCommon.LOCAL_ADDRESS, "--remote-address", REMOTE_ADDRESS2 + "," + REMOTE_ADDRESS3 + "," + REMOTE_ADDRESS4, "--pcc", "2"});
         Thread.sleep(1000);
         //PCE1
-        TestingSessionListener sessionListener1 = factory.getSessionListenerByRemoteAddress(InetAddresses.forString(LOCAL_ADDRESS));
-        TestingSessionListener sessionListener2 = factory.getSessionListenerByRemoteAddress(InetAddresses.forString(LOCAL_ADDRESS2));
-        Assert.assertNotNull(sessionListener1);
-        Assert.assertNotNull(sessionListener2);
-        Assert.assertTrue(sessionListener1.isUp());
-        Assert.assertTrue(sessionListener2.isUp());
-        Assert.assertEquals(2, sessionListener1.messages().size());
-        Assert.assertEquals(2, sessionListener2.messages().size());
+        int numMessages = 2;
+        checkSessionListener(numMessages, channel, factory, PCCMockCommon.LOCAL_ADDRESS);
+        checkSessionListener(numMessages, channel, factory, LOCAL_ADDRESS2);
         //PCE2
-        sessionListener1 = factory2.getSessionListenerByRemoteAddress(InetAddresses.forString(LOCAL_ADDRESS));
-        sessionListener2 = factory2.getSessionListenerByRemoteAddress(InetAddresses.forString(LOCAL_ADDRESS2));
-        Assert.assertNotNull(sessionListener1);
-        Assert.assertNotNull(sessionListener2);
-        Assert.assertTrue(sessionListener1.isUp());
-        Assert.assertTrue(sessionListener2.isUp());
-        Assert.assertEquals(2, sessionListener1.messages().size());
-        Assert.assertEquals(2, sessionListener2.messages().size());
+        checkSessionListener(numMessages, channel2, factory2, LOCAL_ADDRESS);
+        checkSessionListener(numMessages, channel2, factory2, LOCAL_ADDRESS2);
         //PCE3
-        sessionListener1 = factory3.getSessionListenerByRemoteAddress(InetAddresses.forString(LOCAL_ADDRESS));
-        sessionListener2 = factory3.getSessionListenerByRemoteAddress(InetAddresses.forString(LOCAL_ADDRESS2));
-        Assert.assertNotNull(sessionListener1);
-        Assert.assertNotNull(sessionListener2);
-        Assert.assertTrue(sessionListener1.isUp());
-        Assert.assertTrue(sessionListener2.isUp());
-        Assert.assertEquals(2, sessionListener1.messages().size());
-        Assert.assertEquals(2, sessionListener2.messages().size());
-
-        channel.close().get();
-        channel2.close().get();
-        channel3.close().get();
+        checkSessionListener(numMessages, channel3, factory3, PCCMockCommon.LOCAL_ADDRESS);
+        checkSessionListener(numMessages, channel3, factory3, LOCAL_ADDRESS2);
     }
 
-    @Test(expected=UnsupportedOperationException.class)
+    @Test(expected = UnsupportedOperationException.class)
     public void testPrivateConstructor() throws Throwable {
         final Constructor<MsgBuilderUtil> c = MsgBuilderUtil.class.getDeclaredConstructor();
         c.setAccessible(true);
@@ -137,4 +77,14 @@ public class PCCMockTest {
             throw e.getCause();
         }
     }
+
+    @Override
+    protected List<PCEPCapability> getCapabilities() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    protected int getPort() {
+        return 4560;
+    }
 }
index 94c5509637eb7865eb1e953324fe5934b9f0537c..c5c12de5379d95587ad4b8f2799e5e244705fb57 100644 (file)
@@ -20,8 +20,9 @@ import org.mockito.MockitoAnnotations;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 import org.opendaylight.protocol.pcep.PCEPSession;
-import org.opendaylight.protocol.pcep.pcc.mock.api.PccSession;
-import org.opendaylight.protocol.pcep.pcc.mock.api.PccTunnelManager;
+import org.opendaylight.protocol.pcep.pcc.mock.api.PCCSession;
+import org.opendaylight.protocol.pcep.pcc.mock.api.PCCTunnelManager;
+import org.opendaylight.protocol.pcep.pcc.mock.protocol.PCCSessionListener;
 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
@@ -56,7 +57,7 @@ public class PCCSessionListenerTest {
     private PCEPSession mockedSession;
 
     @Mock
-    private PccTunnelManager tunnelManager;
+    private PCCTunnelManager tunnelManager;
 
     private final List<Message> sendMessages = Lists.newArrayList();
 
@@ -81,15 +82,21 @@ public class PCCSessionListenerTest {
     public void testOnMessage() {
         final PCCSessionListener listener = new PCCSessionListener(1, tunnelManager, false);
         listener.onMessage(mockedSession, createUpdMsg(true));
-        Mockito.verify(tunnelManager).reportToAll(Mockito.any(Updates.class), Mockito.any(PccSession.class));
+        Mockito.verify(tunnelManager).onMessagePcupd(Mockito.any(Updates.class), Mockito.any(PCCSession.class));
+        Mockito.verify(tunnelManager, Mockito.never()).onMessagePcInitiate(Mockito.any(Requests.class), Mockito.any(PCCSession.class));
         listener.onMessage(mockedSession, createUpdMsg(false));
-        Mockito.verify(tunnelManager).returnDelegation(Mockito.any(Updates.class), Mockito.any(PccSession.class));
+        Mockito.verify(tunnelManager, Mockito.times(2)).onMessagePcupd(Mockito.any(Updates.class), Mockito.any(PCCSession.class));
+        Mockito.verify(tunnelManager, Mockito.never()).onMessagePcInitiate(Mockito.any(Requests.class), Mockito.any(PCCSession.class));
+
         listener.onMessage(mockedSession, createInitMsg(false, true));
-        Mockito.verify(tunnelManager).addTunnel(Mockito.any(Requests.class), Mockito.any(PccSession.class));
+        Mockito.verify(tunnelManager, Mockito.times(2)).onMessagePcupd(Mockito.any(Updates.class), Mockito.any(PCCSession.class));
+        Mockito.verify(tunnelManager).onMessagePcInitiate(Mockito.any(Requests.class), Mockito.any(PCCSession.class));
         listener.onMessage(mockedSession, createInitMsg(true, false));
-        Mockito.verify(tunnelManager).removeTunnel(Mockito.any(Requests.class), Mockito.any(PccSession.class));
+        Mockito.verify(tunnelManager, Mockito.times(2)).onMessagePcupd(Mockito.any(Updates.class), Mockito.any(PCCSession.class));
+        Mockito.verify(tunnelManager, Mockito.times(2)).onMessagePcInitiate(Mockito.any(Requests.class), Mockito.any(PCCSession.class));
         listener.onMessage(mockedSession, createInitMsg(false, false));
-        Mockito.verify(tunnelManager).takeDelegation(Mockito.any(Requests.class), Mockito.any(PccSession.class));
+        Mockito.verify(tunnelManager, Mockito.times(2)).onMessagePcupd(Mockito.any(Updates.class), Mockito.any(PCCSession.class));
+        Mockito.verify(tunnelManager, Mockito.times(3)).onMessagePcInitiate(Mockito.any(Requests.class), Mockito.any(PCCSession.class));
     }
 
     @Test
@@ -103,14 +110,14 @@ public class PCCSessionListenerTest {
     public void testOnSessionUp() {
         final PCCSessionListener listener = new PCCSessionListener(1, tunnelManager, false);
         listener.onSessionUp(mockedSession);
-        Mockito.verify(tunnelManager).onSessionUp(Mockito.any(PccSession.class));
+        Mockito.verify(tunnelManager).onSessionUp(Mockito.any(PCCSession.class));
     }
 
     @Test
     public void testOnSessionDown() {
         final PCCSessionListener listener = new PCCSessionListener(1, tunnelManager, false);
         listener.onSessionDown(mockedSession, new Exception());
-        Mockito.verify(tunnelManager).onSessionDown(Mockito.any(PccSession.class));
+        Mockito.verify(tunnelManager).onSessionDown(Mockito.any(PCCSession.class));
     }
 
     @Test
@@ -156,8 +163,7 @@ public class PCCSessionListenerTest {
         }
         requests.add(reqBuilder.build());
 
-        final PcinitiateMessageBuilder initBuilder = new PcinitiateMessageBuilder()
-            .setRequests(requests);
+        final PcinitiateMessageBuilder initBuilder = new PcinitiateMessageBuilder().setRequests(requests);
         return new PcinitiateBuilder().setPcinitiateMessage(initBuilder.build()).build();
     }
 
diff --git a/pcep/pcc-mock/src/test/java/org/opendaylight/protocol/pcep/pcc/mock/PCCSyncAvoidanceProcedureTest.java b/pcep/pcc-mock/src/test/java/org/opendaylight/protocol/pcep/pcc/mock/PCCSyncAvoidanceProcedureTest.java
new file mode 100644 (file)
index 0000000..4adf663
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2015 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.junit.Assert.assertNotNull;
+
+import com.google.common.base.Optional;
+import io.netty.channel.Channel;
+import java.math.BigInteger;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import org.junit.Test;
+import org.opendaylight.protocol.pcep.PCEPCapability;
+import org.opendaylight.protocol.pcep.PCEPSession;
+import org.opendaylight.protocol.pcep.ietf.stateful07.PCEPStatefulCapability;
+import org.opendaylight.protocol.pcep.pcc.mock.protocol.PCCPeerProposal;
+
+public class PCCSyncAvoidanceProcedureTest extends PCCMockCommon {
+    @Test
+    public void testSessionAvoidanceDesynchronizedEstablishment() throws UnknownHostException, InterruptedException, ExecutionException {
+        final TestingSessionListenerFactory factory = new TestingSessionListenerFactory();
+
+        final Channel channel = createServer(factory, socket, new PCCPeerProposal());
+        Thread.sleep(200);
+        PCEPSession session = createPCCSession(BigInteger.TEN).get();
+        assertNotNull(session);
+        final TestingSessionListener pceSessionListener = getListener(factory);
+        assertNotNull(pceSessionListener);
+        Thread.sleep(1000);
+        checkResyncSession(Optional.<Integer>absent(), 11, null, BigInteger.valueOf(10), pceSessionListener);
+        channel.close().get();
+    }
+
+    @Override
+    protected List<PCEPCapability> getCapabilities() {
+        final List<PCEPCapability> caps = new ArrayList<>();
+        caps.add(new PCEPStatefulCapability(true, true, true, false, false, false, true));
+        return caps;
+    }
+
+    @Override
+    protected int getPort() {
+        return 4567;
+    }
+}
diff --git a/pcep/pcc-mock/src/test/java/org/opendaylight/protocol/pcep/pcc/mock/PCCTriggeredFullDBResyncTest.java b/pcep/pcc-mock/src/test/java/org/opendaylight/protocol/pcep/pcc/mock/PCCTriggeredFullDBResyncTest.java
new file mode 100644 (file)
index 0000000..b869a66
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2015 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.junit.Assert.assertNotNull;
+
+import com.google.common.base.Optional;
+import io.netty.channel.Channel;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.junit.Test;
+import org.opendaylight.protocol.pcep.PCEPCapability;
+import org.opendaylight.protocol.pcep.PCEPSession;
+import org.opendaylight.protocol.pcep.ietf.stateful07.PCEPStatefulCapability;
+import org.opendaylight.protocol.pcep.pcc.mock.protocol.PCCPeerProposal;
+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.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.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.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.types.rev131005.Message;
+
+public class PCCTriggeredFullDBResyncTest extends PCCMockCommon {
+    private Channel channel;
+
+    @Test
+    public void testSessionTriggeredFullDBReSync() throws Exception {
+        final TestingSessionListenerFactory factory = new TestingSessionListenerFactory();
+        final int lspQuantity = 3;
+        final BigInteger numberOflspAndDBv = BigInteger.valueOf(lspQuantity);
+        this.channel = createServer(factory, socket, new PCCPeerProposal());
+        Thread.sleep(300);
+        PCEPSession session = createPCCSession(numberOflspAndDBv).get();
+        assertNotNull(session);
+        final TestingSessionListener pceSessionListener = getListener(factory);
+        assertNotNull(pceSessionListener);
+        checkSynchronizedSession(lspQuantity, pceSessionListener, numberOflspAndDBv);
+        pccSessionListener.onMessage(session, createTriggerLspResync());
+        Thread.sleep(300);
+        final TestingSessionListener sessionListenerAfterReconnect = getListener(factory);
+        checkResyncSession(Optional.of(lspQuantity), 4, null, numberOflspAndDBv, sessionListenerAfterReconnect);
+        channel.close().get();
+    }
+
+    private Message createTriggerLspResync() {
+        final SrpBuilder srpBuilder = new SrpBuilder();
+        srpBuilder.setOperationId(new SrpIdNumber(1L));
+        srpBuilder.setProcessingRule(Boolean.TRUE);
+
+        final Srp srp = srpBuilder.build();
+        final Lsp lsp = new LspBuilder().setPlspId(new PlspId(Long.valueOf(0))).setSync(Boolean.TRUE).build();
+        final UpdatesBuilder rb = new UpdatesBuilder();
+        rb.setSrp(srp);
+        rb.setLsp(lsp);
+        final PathBuilder pb = new PathBuilder();
+        rb.setPath(pb.build());
+        final PcupdMessageBuilder ub = new PcupdMessageBuilder();
+        ub.setUpdates(Collections.singletonList(rb.build()));
+        return new PcupdBuilder().setPcupdMessage(ub.build()).build();
+    }
+
+    @Override
+    protected List<PCEPCapability> getCapabilities() {
+        final List<PCEPCapability> caps = new ArrayList<>();
+        caps.add(new PCEPStatefulCapability(true, true, true, false, true, false, true));
+        return caps;
+    }
+
+    @Override
+    protected int getPort() {
+        return 4566;
+    }
+}
diff --git a/pcep/pcc-mock/src/test/java/org/opendaylight/protocol/pcep/pcc/mock/PCCTriggeredLspResyncTest.java b/pcep/pcc-mock/src/test/java/org/opendaylight/protocol/pcep/pcc/mock/PCCTriggeredLspResyncTest.java
new file mode 100644 (file)
index 0000000..973655c
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2015 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.junit.Assert.assertNotNull;
+
+import com.google.common.base.Optional;
+import io.netty.channel.Channel;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.junit.Test;
+import org.opendaylight.protocol.pcep.PCEPCapability;
+import org.opendaylight.protocol.pcep.PCEPSession;
+import org.opendaylight.protocol.pcep.ietf.stateful07.PCEPStatefulCapability;
+import org.opendaylight.protocol.pcep.pcc.mock.protocol.PCCPeerProposal;
+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.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.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.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.types.rev131005.Message;
+
+public class PCCTriggeredLspResyncTest extends PCCMockCommon {
+    private Channel channel;
+
+    @Test
+    public void testSessionTriggeredLspReSync() throws Exception {
+        final TestingSessionListenerFactory factory = new TestingSessionListenerFactory();
+        final int lspQuantity = 3;
+        final BigInteger numberOflspAndDBv = BigInteger.valueOf(lspQuantity);
+
+        this.channel = createServer(factory, socket, new PCCPeerProposal());
+        Thread.sleep(200);
+        PCEPSession session = createPCCSession(numberOflspAndDBv).get();
+        assertNotNull(session);
+        final TestingSessionListener pceSessionListener = getListener(factory);
+        assertNotNull(pceSessionListener);
+        checkSynchronizedSession(lspQuantity, pceSessionListener, numberOflspAndDBv);
+        pccSessionListener.onMessage(session, createTriggerLspResync());
+        Thread.sleep(300);
+        final TestingSessionListener sessionListenerAfterReconnect = getListener(factory);
+        checkResyncSession(Optional.of(lspQuantity), 2, null, numberOflspAndDBv, sessionListenerAfterReconnect);
+        channel.close().get();
+    }
+
+    private Message createTriggerLspResync() {
+        final SrpBuilder srpBuilder = new SrpBuilder();
+        srpBuilder.setOperationId(new SrpIdNumber(1L));
+        srpBuilder.setProcessingRule(Boolean.TRUE);
+
+        final Srp srp = srpBuilder.build();
+        final Lsp lsp = new LspBuilder().setPlspId(new PlspId(Long.valueOf(2))).setSync(Boolean.TRUE).build();
+        final UpdatesBuilder rb = new UpdatesBuilder();
+        rb.setSrp(srp);
+        rb.setLsp(lsp);
+        final PathBuilder pb = new PathBuilder();
+        rb.setPath(pb.build());
+        final PcupdMessageBuilder ub = new PcupdMessageBuilder();
+        ub.setUpdates(Collections.singletonList(rb.build()));
+        return new PcupdBuilder().setPcupdMessage(ub.build()).build();
+    }
+
+    @Override
+    protected List<PCEPCapability> getCapabilities() {
+        final List<PCEPCapability> caps = new ArrayList<>();
+        caps.add(new PCEPStatefulCapability(true, true, true, false, true, false, true));
+        return caps;
+    }
+
+    @Override
+    protected int getPort() {
+        return 4584;
+    }
+}
diff --git a/pcep/pcc-mock/src/test/java/org/opendaylight/protocol/pcep/pcc/mock/PCCTriggeredSyncTest.java b/pcep/pcc-mock/src/test/java/org/opendaylight/protocol/pcep/pcc/mock/PCCTriggeredSyncTest.java
new file mode 100644 (file)
index 0000000..2deca62
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2015 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.junit.Assert.assertNotNull;
+
+import io.netty.channel.Channel;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.junit.Test;
+import org.opendaylight.protocol.pcep.PCEPCapability;
+import org.opendaylight.protocol.pcep.PCEPSession;
+import org.opendaylight.protocol.pcep.ietf.stateful07.PCEPStatefulCapability;
+import org.opendaylight.protocol.pcep.pcc.mock.protocol.PCCPeerProposal;
+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.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.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.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.types.rev131005.Message;
+
+public class PCCTriggeredSyncTest extends PCCMockCommon {
+
+    private Channel channel;
+
+    @Test
+    public void testSessionTriggeredSync() throws Exception {
+        final TestingSessionListenerFactory factory = new TestingSessionListenerFactory();
+        this.channel = createServer(factory, socket, new PCCPeerProposal());
+        Thread.sleep(200);
+        final BigInteger numberOflspAndDBv = BigInteger.valueOf(3);
+        PCEPSession session = createPCCSession(numberOflspAndDBv).get();
+        assertNotNull(session);
+        final TestingSessionListener pceSessionListener = getListener(factory);
+        assertNotNull(pceSessionListener);
+        checkSynchronizedSession(0, pceSessionListener, BigInteger.ZERO);
+        pccSessionListener.onMessage(session, createTriggerMsg());
+        Thread.sleep(300);
+        checkSynchronizedSession(3, pceSessionListener, numberOflspAndDBv);
+        this.channel.close().get();
+    }
+
+    private Message createTriggerMsg() {
+        final UpdatesBuilder rb = new UpdatesBuilder();
+        // create PCUpd with mandatory objects and LSP object set to 1
+        final SrpBuilder srpBuilder = new SrpBuilder();
+        srpBuilder.setIgnore(false);
+        srpBuilder.setProcessingRule(false);
+        srpBuilder.setOperationId(new SrpIdNumber(1L));
+        final Srp srp = srpBuilder.build();
+        rb.setSrp(srp);
+
+        final Lsp lsp = new LspBuilder().setPlspId(new PlspId(Long.valueOf(0))).setSync(Boolean.TRUE).build();
+        rb.setLsp(lsp);
+
+        final PathBuilder pb = new PathBuilder();
+        rb.setPath(pb.build());
+        final PcupdMessageBuilder ub = new PcupdMessageBuilder();
+        ub.setUpdates(Collections.singletonList(rb.build()));
+        return new PcupdBuilder().setPcupdMessage(ub.build()).build();
+    }
+
+    @Override
+    protected List<PCEPCapability> getCapabilities() {
+        final List<PCEPCapability> caps = new ArrayList<>();
+        caps.add(new PCEPStatefulCapability(true, true, true, true, false, false, true));
+        return caps;
+    }
+
+    @Override
+    protected int getPort() {
+        return 4582;
+    }
+}
+
index d3f38b36e158aeee1d9b6d5201fb206fcd3e3fb9..4eca81f69fcb40bbc9e836fc7c3e056dd25982fc 100644 (file)
@@ -11,6 +11,7 @@ package org.opendaylight.protocol.pcep.pcc.mock;
 import static org.junit.Assert.assertEquals;
 
 import com.google.common.base.Charsets;
+import com.google.common.base.Optional;
 import com.google.common.collect.Lists;
 import com.google.common.net.InetAddresses;
 import io.netty.util.HashedWheelTimer;
@@ -26,11 +27,13 @@ import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
-import org.opendaylight.protocol.pcep.pcc.mock.api.PccSession;
-import org.opendaylight.protocol.pcep.pcc.mock.api.PccTunnelManager;
+import org.opendaylight.protocol.pcep.pcc.mock.api.PCCSession;
+import org.opendaylight.protocol.pcep.pcc.mock.api.PCCTunnelManager;
 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.Srp1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.Srp1Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.pcinitiate.message.pcinitiate.message.Requests;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.pcinitiate.message.pcinitiate.message.RequestsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.Pcrpt;
@@ -60,15 +63,14 @@ public class PCCTunnelManagerImplTest {
     private static final Ero ERO = new EroBuilder()
         .setSubobject(Lists.newArrayList(new SubobjectBuilder().setSubobjectType(new IpPrefixCaseBuilder().setIpPrefix(
             new IpPrefixBuilder().setIpPrefix(new IpPrefix(new Ipv4Prefix("127.0.0.2/32"))).build()).build()).build())).build();
-
-    @Mock
-    private PccSession session1;
-    @Mock
-    private PccSession session2;
-
     private final List<PCEPErrors> errorsSession1 = new ArrayList<>();
-
     private final List<PCEPErrors> errorsSession2 = new ArrayList<>();
+    @Mock
+    private PCCSession session1;
+    @Mock
+    private PCCSession session2;
+    @Mock
+    private Optional<TimerHandler> timerHandler;
 
     @Before
     public void setUp() {
@@ -101,36 +103,39 @@ public class PCCTunnelManagerImplTest {
 
     @Test
     public void testOnSessionUp() {
-        final PccTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER);
-        tunnelManager.onSessionUp(session1);
-        tunnelManager.onSessionUp(session2);
-        //1 reported LSP + 1 end-of-sync marker
-        Mockito.verify(session1, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
-        //1 reported LSP + 1 end-of-sync marker
-        Mockito.verify(session2, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
+        final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
+        checkSessionUp(session1, tunnelManager);
+        checkSessionUp(session2, tunnelManager);
     }
 
     @Test
     public void testOnSessionDownAndDelegateBack() throws InterruptedException {
-        final PccTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 1, 10, TIMER);
-        tunnelManager.onSessionUp(session1);
-        tunnelManager.onSessionUp(session2);
-        Mockito.verify(session1, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
-        tunnelManager.onSessionDown(session1);
-        Mockito.verify(session1, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
+        final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 1, 10, TIMER, this.timerHandler);
+        checkSessionUp(session1, tunnelManager);
+        checkSessionUp(session2, tunnelManager);
+        checkSessionDown(session1, tunnelManager);
         tunnelManager.onSessionUp(session1);
         Mockito.verify(session1, Mockito.times(4)).sendReport(Mockito.any(Pcrpt.class));
         Mockito.verify(session2, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
     }
 
+    private static void checkSessionDown(final PCCSession session, final PCCTunnelManager tunnelManager) {
+        tunnelManager.onSessionDown(session);
+        Mockito.verify(session, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
+    }
+
+    private static void checkSessionUp(final PCCSession session, final PCCTunnelManager tunnelManager) {
+        //1 reported LSP + 1 end-of-sync marker
+        tunnelManager.onSessionUp(session);
+        Mockito.verify(session, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
+    }
+
     @Test
     public void testOnSessionDownAndDelegateToOther() throws InterruptedException {
-        final PccTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, -1, TIMER);
-        tunnelManager.onSessionUp(session1);
+        final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, -1, TIMER, this.timerHandler);
         tunnelManager.onSessionUp(session2);
-        Mockito.verify(session1, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
-        tunnelManager.onSessionDown(session1);
-        Mockito.verify(session1, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
+        checkSessionUp(session1, tunnelManager);
+        checkSessionDown(session1, tunnelManager);
         //wait for re-delegation timeout expires
         Thread.sleep(500);
         Mockito.verify(session2, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
@@ -140,39 +145,39 @@ public class PCCTunnelManagerImplTest {
 
     @Test
     public void testReportToAll() throws InterruptedException {
-        final PccTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER);
+        final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
         tunnelManager.onSessionUp(session1);
         tunnelManager.onSessionUp(session2);
-        tunnelManager.reportToAll(createUpdate(1), session1);
+        tunnelManager.onMessagePcupd(createUpdateDelegate(1), session1);
         Mockito.verify(session1, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
         Mockito.verify(session2, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
     }
 
     @Test
     public void testReportToAllUnknownLsp() {
-        final PccTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER);
+        final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
         tunnelManager.onSessionUp(session1);
-        tunnelManager.reportToAll(createUpdate(2), session1);
+        tunnelManager.onMessagePcupd(createUpdateDelegate(2), session1);
         Mockito.verify(session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
         assertEquals(PCEPErrors.UNKNOWN_PLSP_ID, errorsSession1.get(0));
     }
 
     @Test
     public void testReportToAllNonDelegatedLsp() {
-        final PccTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER);
+        final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
         tunnelManager.onSessionUp(session1);
         tunnelManager.onSessionUp(session2);
-        tunnelManager.reportToAll(createUpdate(1), session2);
+        tunnelManager.onMessagePcupd(createUpdateDelegate(1), session2);
         Mockito.verify(session2, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
         assertEquals(PCEPErrors.UPDATE_REQ_FOR_NON_LSP, errorsSession2.get(0));
     }
 
     @Test
     public void testReturnDelegationPccLsp() throws InterruptedException {
-        final PccTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 1, -1, TIMER);
+        final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 1, -1, TIMER, this.timerHandler);
         tunnelManager.onSessionUp(session1);
         tunnelManager.onSessionUp(session2);
-        tunnelManager.returnDelegation(createUpdate(1), session1);
+        tunnelManager.onMessagePcupd(createUpdate(1), session1);
         Mockito.verify(session1, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
         Mockito.verify(session2, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
         //wait for re-delegation timer expires
@@ -182,122 +187,133 @@ public class PCCTunnelManagerImplTest {
 
     @Test
     public void testReturnDelegationUnknownLsp() {
-        final PccTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER);
+        final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
         tunnelManager.onSessionUp(session1);
-        tunnelManager.returnDelegation(createUpdate(2), session1);
+        tunnelManager.onMessagePcupd(createUpdate(2), session1);
         Mockito.verify(session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
         assertEquals(PCEPErrors.UNKNOWN_PLSP_ID, errorsSession1.get(0));
     }
 
     @Test
     public void testReturnDelegationNonDelegatedLsp() {
-        final PccTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER);
+        final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
         tunnelManager.onSessionUp(session1);
         tunnelManager.onSessionUp(session2);
-        tunnelManager.returnDelegation(createUpdate(1), session2);
+        tunnelManager.onMessagePcupd(createUpdate(1), session2);
         Mockito.verify(session2, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
         assertEquals(PCEPErrors.UPDATE_REQ_FOR_NON_LSP, errorsSession2.get(0));
     }
 
     @Test
     public void testAddTunnel() {
-        final PccTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER);
+        final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
         tunnelManager.onSessionUp(session1);
         tunnelManager.onSessionUp(session2);
-        tunnelManager.addTunnel(createRequests(1), session1);
+        tunnelManager.onMessagePcInitiate(createRequests(1), session1);
         Mockito.verify(session1, Mockito.times(1)).sendReport(Mockito.any(Pcrpt.class));
         Mockito.verify(session2, Mockito.times(1)).sendReport(Mockito.any(Pcrpt.class));
     }
 
     @Test
     public void testRemoveTunnel() {
-        final PccTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER);
+        final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
         tunnelManager.onSessionUp(session1);
         tunnelManager.onSessionUp(session2);
-        tunnelManager.addTunnel(createRequests(1), session1);
-        tunnelManager.removeTunnel(createRequests(1), session1);
+        tunnelManager.onMessagePcInitiate(createRequests(1), session1);
+        tunnelManager.onMessagePcInitiate(createRequestsRemove(1), session1);
         Mockito.verify(session1, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
         Mockito.verify(session2, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
     }
 
     @Test
     public void testRemoveTunnelUnknownLsp() {
-        final PccTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER);
+        final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
         tunnelManager.onSessionUp(session1);
-        tunnelManager.removeTunnel(createRequests(1), session1);
+        tunnelManager.onMessagePcInitiate(createRequestsRemove(1), session1);
         Mockito.verify(session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
         assertEquals(PCEPErrors.UNKNOWN_PLSP_ID, errorsSession1.get(0));
     }
 
     @Test
     public void testRemoveTunnelNotPceInitiatedLsp() {
-        final PccTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER);
+        final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
         tunnelManager.onSessionUp(session1);
-        tunnelManager.removeTunnel(createRequests(1), session1);
+        tunnelManager.onMessagePcInitiate(createRequestsRemove(1), session1);
         Mockito.verify(session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
         assertEquals(PCEPErrors.LSP_NOT_PCE_INITIATED, errorsSession1.get(0));
     }
 
     @Test
     public void testRemoveTunnelNotDelegated() {
-        final PccTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER);
+        final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
         tunnelManager.onSessionUp(session1);
         tunnelManager.onSessionUp(session2);
-        tunnelManager.addTunnel(createRequests(1), session1);
-        tunnelManager.removeTunnel(createRequests(1), session2);
+        tunnelManager.onMessagePcInitiate(createRequests(1), session1);
+        tunnelManager.onMessagePcInitiate(createRequestsRemove(1), session2);
         Mockito.verify(session2, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
         assertEquals(PCEPErrors.UPDATE_REQ_FOR_NON_LSP, errorsSession2.get(0));
     }
 
     @Test
     public void testTakeDelegation() throws InterruptedException {
-        final PccTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, -1, TIMER);
+        final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, -1, TIMER, this.timerHandler);
         tunnelManager.onSessionUp(session1);
         tunnelManager.onSessionUp(session2);
-        tunnelManager.addTunnel(createRequests(1), session1);
-        tunnelManager.returnDelegation(createUpdate(1), session1);
+        tunnelManager.onMessagePcInitiate(createRequests(1), session1); //AddTunel
+        tunnelManager.onMessagePcupd(createUpdate(1), session1); //returnDelegation
         Mockito.verify(session1, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
         Mockito.verify(session2, Mockito.times(1)).sendReport(Mockito.any(Pcrpt.class));
         Thread.sleep(500);
-        tunnelManager.takeDelegation(createRequests(1), session2);
+        tunnelManager.onMessagePcInitiate(createRequestsDelegate(1), session2);//takeDelegation
         Mockito.verify(session1, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
         Mockito.verify(session2, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
     }
 
     @Test
     public void testTakeDelegationUnknownLsp() {
-        final PccTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER);
+        final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
         tunnelManager.onSessionUp(session1);
-        tunnelManager.takeDelegation(createRequests(1), session1);
+        tunnelManager.onMessagePcInitiate(createRequestsDelegate(1), session1);
         Mockito.verify(session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
         assertEquals(PCEPErrors.UNKNOWN_PLSP_ID, errorsSession1.get(0));
     }
 
     @Test
     public void testTakeDelegationNotPceInitiatedLsp() {
-        final PccTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER);
+        final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
         tunnelManager.onSessionUp(session1);
-        tunnelManager.takeDelegation(createRequests(1), session1);
+        tunnelManager.onMessagePcInitiate(createRequestsDelegate(1), session1);
         Mockito.verify(session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
         assertEquals(PCEPErrors.LSP_NOT_PCE_INITIATED, errorsSession1.get(0));
     }
 
     @Test
     public void testReturnDelegationNoRetake() throws InterruptedException {
-        final PccTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER);
+        final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
         tunnelManager.onSessionUp(session1);
         tunnelManager.onSessionUp(session2);
-        tunnelManager.addTunnel(createRequests(1), session1);
-        tunnelManager.returnDelegation(createUpdate(1), session1);
+        tunnelManager.onMessagePcInitiate(createRequests(1), session1);
+        tunnelManager.onMessagePcupd(createUpdate(1), session1);
         //wait for state timeout expires
         Thread.sleep(500);
         Mockito.verify(session1, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
         Mockito.verify(session2, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
     }
+    private Updates createUpdateDelegate(final long plspId) {
+        return createUpdate(plspId, Optional.of(true));
+    }
+
+    private Updates createUpdate(final long plspId) {
+        return createUpdate(plspId, Optional.<Boolean>absent());
+    }
 
-    private static Updates createUpdate(final long plspId) {
+    private static Updates createUpdate(final long plspId, final Optional<Boolean> delegate) {
         final UpdatesBuilder updsBuilder = new UpdatesBuilder();
-        updsBuilder.setLsp(new LspBuilder().setPlspId(new PlspId(plspId)).build());
+        final LspBuilder lsp = new LspBuilder().setPlspId(new PlspId(plspId));
+        if (delegate.isPresent()) {
+            lsp.setDelegate(true);
+        }
+        updsBuilder.setLsp(lsp.build());
         final PathBuilder pathBuilder = new PathBuilder();
         pathBuilder.setEro(ERO);
         updsBuilder.setPath(pathBuilder.build());
@@ -305,19 +321,39 @@ public class PCCTunnelManagerImplTest {
         return updsBuilder.build();
     }
 
-    private static Requests createRequests(final long plspId) {
+    private static Requests createRequests(final long plspId, final Optional<Boolean> remove, final Optional<Boolean> delegate) {
         final RequestsBuilder reqBuilder = new RequestsBuilder();
         reqBuilder.setEro(ERO);
-        reqBuilder.setLsp(new LspBuilder()
-            .setTlvs(new TlvsBuilder().setSymbolicPathName(new SymbolicPathNameBuilder().setPathName(new SymbolicPathName(SYMBOLIC_NAME)).build()).build())
-            .setPlspId(new PlspId(plspId)).build());
-        reqBuilder.setSrp(new SrpBuilder().setOperationId(new SrpIdNumber(0L)).build());
+        final LspBuilder lsp = new LspBuilder().setTlvs(new TlvsBuilder().setSymbolicPathName(new SymbolicPathNameBuilder().setPathName(
+            new SymbolicPathName(SYMBOLIC_NAME)).build()).build()).setPlspId(new PlspId(plspId));
+        if (delegate.isPresent()) {
+            lsp.setDelegate(true);
+        }
+
+        reqBuilder.setLsp(lsp.build());
+        final SrpBuilder srpBuilder = new SrpBuilder();
+        if (remove.isPresent()) {
+            srpBuilder.addAugmentation(Srp1.class, new Srp1Builder().setRemove(true).build());
+        }
+        reqBuilder.setSrp(srpBuilder.setOperationId(new SrpIdNumber(0L)).build());
         return reqBuilder.build();
     }
 
+    private static Requests createRequestsRemove(final long plspId) {
+        return createRequests(plspId, Optional.of(true), Optional.<Boolean>absent());
+    }
+
+    private static Requests createRequestsDelegate(final long plspId) {
+        return createRequests(plspId, Optional.<Boolean>absent(), Optional.of(true));
+    }
+
+    private static Requests createRequests(final long plspId) {
+        return createRequests(plspId, Optional.<Boolean>absent(), Optional.<Boolean>absent());
+    }
+
     private static PCEPErrors getError(final Pcerr errorMessage) {
         final ErrorObject errorObject = errorMessage.getPcerrMessage().getErrors().get(0).getErrorObject();
         return PCEPErrors.forValue(errorObject.getType(), errorObject.getValue());
     }
 
-}
+}
\ No newline at end of file
index 96caa3901e12e060b0b3fcecd5e38e2c8fd22724..c9c8057651d4a4d6b793cd80e830ec291976aa09 100644 (file)
@@ -18,7 +18,7 @@ import org.opendaylight.protocol.pcep.PCEPSessionNegotiatorFactory;
 import org.opendaylight.protocol.pcep.PCEPSessionProposalFactory;
 import org.opendaylight.protocol.pcep.impl.BasePCEPSessionProposalFactory;
 import org.opendaylight.protocol.pcep.impl.DefaultPCEPSessionNegotiatorFactory;
-import org.opendaylight.protocol.pcep.pcc.mock.PCCDispatcherImpl;
+import org.opendaylight.protocol.pcep.pcc.mock.protocol.PCCDispatcherImpl;
 import org.opendaylight.protocol.pcep.spi.pojo.ServiceLoaderPCEPExtensionProviderContext;
 
 public class PCCMock {