Bug-5023: Simplify client re-connection strategies
[bgpcep.git] / pcep / pcc-mock / src / main / java / org / opendaylight / protocol / pcep / pcc / mock / Main.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.protocol.pcep.pcc.mock;
10
11 import ch.qos.logback.classic.Level;
12 import ch.qos.logback.classic.LoggerContext;
13 import com.google.common.base.Function;
14 import com.google.common.base.Optional;
15 import com.google.common.base.Preconditions;
16 import com.google.common.base.Predicate;
17 import com.google.common.collect.Iterables;
18 import com.google.common.collect.Lists;
19 import com.google.common.net.HostAndPort;
20 import com.google.common.net.InetAddresses;
21 import java.math.BigInteger;
22 import java.net.InetAddress;
23 import java.net.InetSocketAddress;
24 import java.net.UnknownHostException;
25 import java.util.Arrays;
26 import java.util.List;
27 import java.util.concurrent.ExecutionException;
28 import org.opendaylight.protocol.pcep.PCEPCapability;
29 import org.opendaylight.protocol.pcep.ietf.stateful07.PCEPStatefulCapability;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 public final class Main {
34
35     private static final Logger LOG = LoggerFactory.getLogger(Main.class);
36
37     private static final int DEFAULT_REMOTE_PORT = 4189;
38     private static final int DEFAULT_LOCAL_PORT = 0;
39     private static final short DEFAULT_KEEP_ALIVE = 30;
40     private static final short DEFAULT_DEAD_TIMER = 120;
41     private static final InetAddress LOCALHOST = InetAddresses.forString("127.0.0.1");
42     private static boolean triggeredInitSync = Boolean.FALSE;
43     private static boolean includeDbv = Boolean.FALSE;
44     private static boolean incrementalSync = Boolean.FALSE;
45     private static boolean triggeredResync = Boolean.FALSE;
46     private static BigInteger syncOptDBVersion;
47     private static int reconnectAfterXSeconds;
48     private static int disonnectAfterXSeconds;
49
50
51     private Main() {
52         throw new UnsupportedOperationException();
53     }
54
55     public static void main(final String[] args) throws InterruptedException, ExecutionException, UnknownHostException {
56         InetSocketAddress localAddress = new InetSocketAddress(LOCALHOST, DEFAULT_LOCAL_PORT);
57         List<InetSocketAddress> remoteAddress = Lists.newArrayList(new InetSocketAddress(LOCALHOST, DEFAULT_REMOTE_PORT));
58         int pccCount = 1;
59         int lsps = 1;
60         boolean pcError = false;
61         final LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
62         short ka = DEFAULT_KEEP_ALIVE;
63         short dt = DEFAULT_DEAD_TIMER;
64         String password = null;
65         long reconnectTime = -1;
66         int redelegationTimeout = 0;
67         int stateTimeout = -1;
68
69         getRootLogger(lc).setLevel(ch.qos.logback.classic.Level.INFO);
70         int argIdx = 0;
71         while (argIdx < args.length) {
72             if (args[argIdx].equals("--local-address")) {
73                 localAddress = getInetSocketAddress(args[++argIdx], DEFAULT_LOCAL_PORT);
74             } else if (args[argIdx].equals("--remote-address")) {
75                 remoteAddress = parseAddresses(args[++argIdx], DEFAULT_REMOTE_PORT);
76             } else if (args[argIdx].equals("--pcc")) {
77                 pccCount = Integer.valueOf(args[++argIdx]);
78             } else if (args[argIdx].equals("--lsp")) {
79                 lsps = Integer.valueOf(args[++argIdx]);
80             } else if (args[argIdx].equals("--pcerr")) {
81                 pcError = true;
82             } else if (args[argIdx].equals("--log-level")) {
83                 getRootLogger(lc).setLevel(Level.toLevel(args[++argIdx], ch.qos.logback.classic.Level.INFO));
84             } else if (args[argIdx].equals("--keepalive") || args[argIdx].equals("-ka")) {
85                 ka = Short.valueOf(args[++argIdx]);
86             } else if (args[argIdx].equals("--deadtimer") || args[argIdx].equals("-d")) {
87                 dt = Short.valueOf(args[++argIdx]);
88             } else if (args[argIdx].equals("--password")) {
89                 password = args[++argIdx];
90             } else if (args[argIdx].equals("--reconnect")) {
91                 reconnectTime = Integer.valueOf(args[++argIdx]).intValue();
92             } else if (args[argIdx].equals("--redelegation-timeout")) {
93                 redelegationTimeout = Integer.valueOf(args[++argIdx]);
94             } else if (args[argIdx].equals("--state-timeout")) {
95                 stateTimeout = Integer.valueOf(args[++argIdx]);
96             } else if (args[argIdx].equals("--state-sync-avoidance")) {
97                 //"--state-sync-avoidance 10, 5, 10
98                 includeDbv = Boolean.TRUE;
99                 final Long dbVersionAfterReconnect = Long.valueOf(args[++argIdx]);
100                 disonnectAfterXSeconds = Integer.valueOf(args[++argIdx]);
101                 reconnectAfterXSeconds = Integer.valueOf(args[++argIdx]);
102                 syncOptDBVersion = BigInteger.valueOf(dbVersionAfterReconnect);
103             } else if (args[argIdx].equals("--incremental-sync-procedure")) {
104                 //TODO Check that DBv > Lsp always ??
105                 includeDbv = Boolean.TRUE;
106                 incrementalSync = Boolean.TRUE;
107                 //Version of database to be used after restart
108                 final Long initialDbVersionAfterReconnect = Long.valueOf(args[++argIdx]);
109                 disonnectAfterXSeconds = Integer.valueOf(args[++argIdx]);
110                 reconnectAfterXSeconds = Integer.valueOf(args[++argIdx]);
111                 syncOptDBVersion = BigInteger.valueOf(initialDbVersionAfterReconnect);
112             } else if (args[argIdx].equals("--triggered-initial-sync")) {
113                 triggeredInitSync = Boolean.TRUE;
114             } else if (args[argIdx].equals("--triggered-re-sync")) {
115                 triggeredResync = Boolean.TRUE;
116             } else {
117                 LOG.warn("WARNING: Unrecognized argument: {}", args[argIdx]);
118             }
119             argIdx++;
120         }
121
122         if (incrementalSync) {
123             Preconditions.checkArgument(syncOptDBVersion.intValue() > lsps, "Synchronization Database Version which will be used after " +
124                 "reconnectes requires to be higher than lsps");
125         }
126
127         final Optional<BigInteger> dBVersion = Optional.fromNullable(syncOptDBVersion);
128         final PCCsBuilder pccs = new PCCsBuilder(lsps, pcError, pccCount, localAddress, remoteAddress, ka, dt, password, reconnectTime, redelegationTimeout,
129             stateTimeout, getCapabilities());
130         final TimerHandler timerHandler = new TimerHandler(pccs, dBVersion, disonnectAfterXSeconds, reconnectAfterXSeconds);
131         pccs.createPCCs(BigInteger.valueOf(lsps), Optional.fromNullable(timerHandler));
132         if (!triggeredInitSync) {
133             timerHandler.createDisconnectTask();
134         }
135     }
136
137     private static PCEPCapability getCapabilities() {
138         if (triggeredInitSync) {
139             Preconditions.checkArgument(includeDbv);
140         }
141         return new PCEPStatefulCapability(true, true, true, triggeredInitSync, triggeredResync, incrementalSync, includeDbv);
142     }
143
144     private static ch.qos.logback.classic.Logger getRootLogger(final LoggerContext lc) {
145         return Iterables.find(lc.getLoggerList(), new Predicate<Logger>() {
146             @Override
147             public boolean apply(final Logger input) {
148                 return (input != null) ? input.getName().equals(Logger.ROOT_LOGGER_NAME) : false;
149             }
150         });
151     }
152
153     private static List<InetSocketAddress> parseAddresses(final String address, final int defaultPort) {
154         return Lists.transform(Arrays.asList(address.split(",")), new Function<String, InetSocketAddress>() {
155             @Override
156             public InetSocketAddress apply(final String input) {
157                 return getInetSocketAddress(input, defaultPort);
158             }
159         });
160     }
161
162     private static InetSocketAddress getInetSocketAddress(final String hostPortString, final int defaultPort) {
163         final HostAndPort hostAndPort = HostAndPort.fromString(hostPortString).withDefaultPort(defaultPort);
164         return new InetSocketAddress(hostAndPort.getHostText(), hostAndPort.getPort());
165     }
166
167 }