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