blob: 9edddc1ef2fc4e7ccf35521a2f9260d38a1f13f2 [file] [log] [blame]
Pingping32fa30c2014-10-23 15:24:26 -07001package org.onlab.onos.sdnip;
2
3import java.util.HashSet;
4import java.util.Random;
5import java.util.Set;
6import java.util.concurrent.Executors;
7import java.util.concurrent.ScheduledExecutorService;
8import java.util.concurrent.TimeUnit;
9
10import org.onlab.onos.net.ConnectPoint;
11import org.onlab.onos.net.DefaultHost;
12import org.onlab.onos.net.DeviceId;
13import org.onlab.onos.net.Host;
14import org.onlab.onos.net.HostId;
15import org.onlab.onos.net.HostLocation;
16import org.onlab.onos.net.host.HostEvent;
17import org.onlab.onos.net.host.HostListener;
18import org.onlab.onos.net.host.HostService;
19import org.onlab.onos.net.host.PortAddresses;
20import org.onlab.onos.net.provider.ProviderId;
21import org.onlab.onos.sdnip.Router.InternalHostListener;
22import org.onlab.packet.IpAddress;
23import org.onlab.packet.MacAddress;
24import org.onlab.packet.VlanId;
25
26import com.google.common.collect.Sets;
27
28/**
29 * Test version of the HostService which is used to simulate delays in
30 * receiving ARP replies, as you would see in a real system due to the time
31 * it takes to proxy ARP packets to/from the host. Requests are asynchronous,
32 * and replies may come back to the requestor in a different order than the
33 * requests were sent, which again you would expect to see in a real system.
34 */
35public class TestHostService implements HostService {
36
37 /**
38 * The maximum possible delay before an ARP reply is received.
39 */
40 private static final int MAX_ARP_REPLY_DELAY = 30; // milliseconds
41
42 /**
43 * The probability that we already have the MAC address cached when the
44 * caller calls {@link #getHostsByIp(IpAddress ipAddress)}.
45 */
46 private static final float MAC_ALREADY_KNOWN_PROBABILITY = 0.3f;
47
48 private final ScheduledExecutorService replyTaskExecutor;
49 private final Random random;
50
51 /**
52 * Class constructor.
53 */
54 public TestHostService() {
55 replyTaskExecutor = Executors.newSingleThreadScheduledExecutor();
56 random = new Random();
57 }
58
59 /**
60 * Task used to reply to ARP requests from a different thread. Replies
61 * usually come on a different thread in the real system, so we need to
62 * ensure we test this behavior.
63 */
64 private class ReplyTask implements Runnable {
65 private HostListener listener;
66 private IpAddress ipAddress;
67
68 /**
69 * Class constructor.
70 *
71 * @param listener the client who requests and waits the MAC address
72 * @param ipAddress the target IP address of the request
73 */
74 public ReplyTask(InternalHostListener listener,
75 IpAddress ipAddress) {
76 this.listener = listener;
77 this.ipAddress = ipAddress;
78 }
79
80 @Override
81 public void run() {
82 Host host = getHostsByIp(ipAddress).iterator().next();
83 HostEvent hostevent =
84 new HostEvent(HostEvent.Type.HOST_ADDED, host);
85 listener.event(hostevent);
86 }
87 }
88
89 @Override
90 public Set<Host> getHostsByIp(IpAddress ipAddress) {
91 float replyChance = random.nextFloat();
92
93 // We don't care what the attachment point is in the test,
94 // so for all the hosts, we use a same ConnectPoint.
95 Host host = new DefaultHost(ProviderId.NONE, HostId.NONE,
96 SdnIpTest.generateMacAddress(ipAddress), VlanId.NONE,
97 new HostLocation(SdnIpTest.SW1_ETH1, 1),
98 Sets.newHashSet(ipAddress));
99
100 if (replyChance < MAC_ALREADY_KNOWN_PROBABILITY) {
101 // Some percentage of the time we already know the MAC address, so
102 // we reply directly when the requestor asks for the MAC address
103 return Sets.newHashSet(host);
104 }
105 return new HashSet<Host>();
106 }
107
108 @Override
109 public void startMonitoringIp(IpAddress ipAddress) {
110
111 // Randomly select an amount of time to delay the reply coming back to
112 int delay = random.nextInt(MAX_ARP_REPLY_DELAY);
113 ReplyTask replyTask = new ReplyTask(
114 (SdnIpTest.router.new InternalHostListener()), ipAddress);
115 replyTaskExecutor.schedule(replyTask, delay, TimeUnit.MILLISECONDS);
116 }
117
118 @Override
119 public int getHostCount() {
120 return 0;
121 }
122
123 @Override
124 public Iterable<Host> getHosts() {
125 return null;
126 }
127
128 @Override
129 public Host getHost(HostId hostId) {
130 return null;
131 }
132
133 @Override
134 public Set<Host> getHostsByVlan(VlanId vlanId) {
135 return null;
136 }
137
138 @Override
139 public Set<Host> getHostsByMac(MacAddress mac) {
140 return null;
141 }
142
143 @Override
144 public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
145 return null;
146 }
147
148 @Override
149 public Set<Host> getConnectedHosts(DeviceId deviceId) {
150 return null;
151 }
152
153 @Override
154 public void stopMonitoringIp(IpAddress ip) {
155
156 }
157
158 @Override
159 public void requestMac(IpAddress ip) {
160
161 }
162
163 @Override
164 public Set<PortAddresses> getAddressBindings() {
165 return null;
166 }
167
168 @Override
169 public Set<PortAddresses> getAddressBindingsForPort(ConnectPoint connectPoint) {
170 return null;
171 }
172
173 @Override
174 public void addListener(HostListener listener) {
175
176 }
177
178 @Override
179 public void removeListener(HostListener listener) {
180
181 }
182
183}