Jonathan Hart
Committed by Gerrit Code Review

Add CLI for viewing FPM connections.

Change-Id: I7e9e320b662a826cd2c0d49477b45110094d8e79
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.routing.fpm;
18 +
19 +import java.net.SocketAddress;
20 +import java.util.Map;
21 +
22 +/**
23 + * Created by jono on 2/2/16.
24 + */
25 +public interface FpmInfoService {
26 +
27 + Map<SocketAddress, Long> peers();
28 +}
...@@ -18,10 +18,12 @@ package org.onosproject.routing.fpm; ...@@ -18,10 +18,12 @@ package org.onosproject.routing.fpm;
18 18
19 import org.onosproject.routing.fpm.protocol.FpmHeader; 19 import org.onosproject.routing.fpm.protocol.FpmHeader;
20 20
21 +import java.net.SocketAddress;
22 +
21 /** 23 /**
22 - * Listener for FPM messages. 24 + * Listener for events from the route source.
23 */ 25 */
24 -public interface FpmMessageListener { 26 +public interface FpmListener {
25 27
26 /** 28 /**
27 * Handles an FPM message. 29 * Handles an FPM message.
...@@ -29,4 +31,19 @@ public interface FpmMessageListener { ...@@ -29,4 +31,19 @@ public interface FpmMessageListener {
29 * @param fpmMessage FPM message 31 * @param fpmMessage FPM message
30 */ 32 */
31 void fpmMessage(FpmHeader fpmMessage); 33 void fpmMessage(FpmHeader fpmMessage);
34 +
35 + /**
36 + * Signifies that a new peer has attempted to initiate an FPM connection.
37 + *
38 + * @param address remote address of the peer
39 + * @return true if the connection should be admitted, otherwise false
40 + */
41 + boolean peerConnected(SocketAddress address);
42 +
43 + /**
44 + * Signifies that an FPM connection has been disconnected.
45 + *
46 + * @param address remote address of the peer
47 + */
48 + void peerDisconnected(SocketAddress address);
32 } 49 }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
15 */ 15 */
16 package org.onosproject.routing.fpm; 16 package org.onosproject.routing.fpm;
17 17
18 +import com.google.common.collect.ImmutableMap;
18 import org.apache.felix.scr.annotations.Activate; 19 import org.apache.felix.scr.annotations.Activate;
19 import org.apache.felix.scr.annotations.Component; 20 import org.apache.felix.scr.annotations.Component;
20 import org.apache.felix.scr.annotations.Deactivate; 21 import org.apache.felix.scr.annotations.Deactivate;
...@@ -46,6 +47,7 @@ import org.slf4j.Logger; ...@@ -46,6 +47,7 @@ import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory; 47 import org.slf4j.LoggerFactory;
47 48
48 import java.net.InetSocketAddress; 49 import java.net.InetSocketAddress;
50 +import java.net.SocketAddress;
49 import java.util.Collections; 51 import java.util.Collections;
50 import java.util.Map; 52 import java.util.Map;
51 import java.util.concurrent.ConcurrentHashMap; 53 import java.util.concurrent.ConcurrentHashMap;
...@@ -58,13 +60,15 @@ import static org.onlab.util.Tools.groupedThreads; ...@@ -58,13 +60,15 @@ import static org.onlab.util.Tools.groupedThreads;
58 */ 60 */
59 @Service 61 @Service
60 @Component(immediate = true, enabled = false) 62 @Component(immediate = true, enabled = false)
61 -public class FpmManager implements RouteSourceService { 63 +public class FpmManager implements RouteSourceService, FpmInfoService {
62 private final Logger log = LoggerFactory.getLogger(getClass()); 64 private final Logger log = LoggerFactory.getLogger(getClass());
63 65
64 private ServerBootstrap serverBootstrap; 66 private ServerBootstrap serverBootstrap;
65 private Channel serverChannel; 67 private Channel serverChannel;
66 private ChannelGroup allChannels = new DefaultChannelGroup(); 68 private ChannelGroup allChannels = new DefaultChannelGroup();
67 69
70 + private Map<SocketAddress, Long> peers = new ConcurrentHashMap<>();
71 +
68 private Map<IpPrefix, RouteEntry> fpmRoutes = new ConcurrentHashMap<>(); 72 private Map<IpPrefix, RouteEntry> fpmRoutes = new ConcurrentHashMap<>();
69 73
70 private RouteListener routeListener; 74 private RouteListener routeListener;
...@@ -209,11 +213,31 @@ public class FpmManager implements RouteSourceService { ...@@ -209,11 +213,31 @@ public class FpmManager implements RouteSourceService {
209 routeListener.update(Collections.singletonList(routeUpdate)); 213 routeListener.update(Collections.singletonList(routeUpdate));
210 } 214 }
211 215
212 - private class InternalFpmListener implements FpmMessageListener { 216 + @Override
217 + public Map<SocketAddress, Long> peers() {
218 + return ImmutableMap.copyOf(peers);
219 + }
220 +
221 + private class InternalFpmListener implements FpmListener {
213 @Override 222 @Override
214 public void fpmMessage(FpmHeader fpmMessage) { 223 public void fpmMessage(FpmHeader fpmMessage) {
215 FpmManager.this.fpmMessage(fpmMessage); 224 FpmManager.this.fpmMessage(fpmMessage);
216 } 225 }
226 +
227 + @Override
228 + public boolean peerConnected(SocketAddress address) {
229 + if (peers.keySet().contains(address)) {
230 + return false;
231 + }
232 +
233 + peers.put(address, System.currentTimeMillis());
234 + return true;
235 + }
236 +
237 + @Override
238 + public void peerDisconnected(SocketAddress address) {
239 + peers.remove(address);
240 + }
217 } 241 }
218 242
219 } 243 }
......
...@@ -35,7 +35,7 @@ public class FpmSessionHandler extends SimpleChannelHandler { ...@@ -35,7 +35,7 @@ public class FpmSessionHandler extends SimpleChannelHandler {
35 35
36 private static Logger log = LoggerFactory.getLogger(FpmSessionHandler.class); 36 private static Logger log = LoggerFactory.getLogger(FpmSessionHandler.class);
37 37
38 - private final FpmMessageListener fpmListener; 38 + private final FpmListener fpmListener;
39 39
40 private Channel channel; 40 private Channel channel;
41 41
...@@ -44,7 +44,7 @@ public class FpmSessionHandler extends SimpleChannelHandler { ...@@ -44,7 +44,7 @@ public class FpmSessionHandler extends SimpleChannelHandler {
44 * 44 *
45 * @param fpmListener listener for FPM messages 45 * @param fpmListener listener for FPM messages
46 */ 46 */
47 - public FpmSessionHandler(FpmMessageListener fpmListener) { 47 + public FpmSessionHandler(FpmListener fpmListener) {
48 this.fpmListener = checkNotNull(fpmListener); 48 this.fpmListener = checkNotNull(fpmListener);
49 } 49 }
50 50
...@@ -59,26 +59,27 @@ public class FpmSessionHandler extends SimpleChannelHandler { ...@@ -59,26 +59,27 @@ public class FpmSessionHandler extends SimpleChannelHandler {
59 public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) 59 public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
60 throws Exception { 60 throws Exception {
61 log.error("Exception thrown while handling FPM message", e.getCause()); 61 log.error("Exception thrown while handling FPM message", e.getCause());
62 + if (channel != null) {
62 channel.close(); 63 channel.close();
64 + }
63 handleDisconnect(); 65 handleDisconnect();
64 } 66 }
65 67
66 @Override 68 @Override
67 public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) 69 public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
68 throws Exception { 70 throws Exception {
69 - if (this.channel != null) { 71 + if (!fpmListener.peerConnected(ctx.getChannel().getRemoteAddress())) {
70 log.error("Received new FPM connection while already connected"); 72 log.error("Received new FPM connection while already connected");
71 ctx.getChannel().close(); 73 ctx.getChannel().close();
72 return; 74 return;
73 } 75 }
74 76
75 - this.channel = ctx.getChannel(); 77 + channel = ctx.getChannel();
76 } 78 }
77 79
78 @Override 80 @Override
79 public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) 81 public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
80 throws Exception { 82 throws Exception {
81 - super.channelConnected(ctx, e);
82 } 83 }
83 84
84 @Override 85 @Override
...@@ -94,6 +95,7 @@ public class FpmSessionHandler extends SimpleChannelHandler { ...@@ -94,6 +95,7 @@ public class FpmSessionHandler extends SimpleChannelHandler {
94 } 95 }
95 96
96 private void handleDisconnect() { 97 private void handleDisconnect() {
97 - this.channel = null; 98 + fpmListener.peerDisconnected(channel.getRemoteAddress());
99 + channel = null;
98 } 100 }
99 } 101 }
......
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.routing.fpm.cli;
18 +
19 +import org.apache.karaf.shell.commands.Command;
20 +import org.onlab.util.Tools;
21 +import org.onosproject.cli.AbstractShellCommand;
22 +import org.onosproject.routing.fpm.FpmInfoService;
23 +
24 +import java.net.InetSocketAddress;
25 +
26 +/**
27 + * Displays the current FPM connections.
28 + */
29 +@Command(scope = "onos", name = "fpm-connections",
30 + description = "Displays the current FPM connections")
31 +public class FpmConnectionsList extends AbstractShellCommand {
32 +
33 + private static final String FORMAT = "%s:%s connected since %s";
34 +
35 + @Override
36 + protected void execute() {
37 + FpmInfoService fpmInfo = get(FpmInfoService.class);
38 +
39 + fpmInfo.peers().forEach((socketAddress, timestamp) -> {
40 + if (socketAddress instanceof InetSocketAddress) {
41 + InetSocketAddress inet = (InetSocketAddress) socketAddress;
42 +
43 + print(FORMAT, inet.getHostString(), inet.getPort(), Tools.timeAgo(timestamp));
44 + } else {
45 + print("Unknown data format");
46 + }
47 + });
48 + }
49 +}
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +/**
18 + * FPM-related CLI commands.
19 + */
20 +package org.onosproject.routing.fpm.cli;
...@@ -49,5 +49,8 @@ ...@@ -49,5 +49,8 @@
49 <command> 49 <command>
50 <action class="org.onosproject.routing.cli.RemovePeerCommand"/> 50 <action class="org.onosproject.routing.cli.RemovePeerCommand"/>
51 </command> 51 </command>
52 + <command>
53 + <action class="org.onosproject.routing.fpm.cli.FpmConnectionsList"/>
54 + </command>
52 </command-bundle> 55 </command-bundle>
53 </blueprint> 56 </blueprint>
......