Open Kilda Java Documentation
StubServiceFactory.java
Go to the documentation of this file.
1 /* Copyright 2018 Telstra Open Source
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 package org.openkilda.atdd.staging.service;
17 
18 import static java.util.Arrays.asList;
19 import static java.util.Collections.emptyList;
20 import static java.util.Collections.singletonList;
21 import static java.util.stream.Collectors.toList;
22 import static org.mockito.ArgumentMatchers.any;
23 import static org.mockito.Mockito.mock;
24 import static org.mockito.Mockito.when;
25 
62 
63 import org.apache.commons.lang3.SerializationUtils;
64 import org.mockito.stubbing.Answer;
65 
66 import java.time.LocalTime;
67 import java.util.ArrayList;
68 import java.util.Arrays;
69 import java.util.HashMap;
70 import java.util.List;
71 import java.util.Map;
72 import java.util.stream.Stream;
73 
78 public class StubServiceFactory {
79 
80  private final Map<String, FlowPayload> flowPayloads = new HashMap<>();
81  private final Map<String, ImmutablePair<Flow, Flow>> flows = new HashMap<>();
82  private int meterCounter = 1;
83 
84  private final TopologyDefinition topologyDefinition;
85 
86  public StubServiceFactory(TopologyDefinition topologyDefinition) {
87  this.topologyDefinition = topologyDefinition;
88  }
89 
94  TopologyEngineService serviceMock = mock(TopologyEngineService.class);
95 
96  when(serviceMock.getFlow(any()))
97  .thenAnswer(invocation -> {
98  String flowId = (String) invocation.getArguments()[0];
99  return flows.get(flowId);
100  });
101 
102  when(serviceMock.getPaths(any(), any()))
103  .thenReturn(Arrays.asList(new PathInfoData(), new PathInfoData()));
104 
105  return serviceMock;
106  }
107 
112  FloodlightService serviceMock = mock(FloodlightService.class);
113 
114  when(serviceMock.getFlows(any()))
115  .thenAnswer(invocation -> {
116  SwitchId switchId = (SwitchId) invocation.getArguments()[0];
117  String switchVersion = topologyDefinition.getActiveSwitches().stream()
118  .filter(sw -> sw.getDpId().equals(switchId))
119  .map(Switch::getOfVersion)
120  .findAny()
121  .orElse("OF_13");
122 
123  return buildFlowEntries(switchId, switchVersion);
124  });
125 
126  when(serviceMock.getMeters(any()))
127  .then((Answer<MetersEntriesMap>) invocation -> {
128  SwitchId switchId = (SwitchId) invocation.getArguments()[0];
129 
131  flows.values().forEach(flowPair -> {
132  if (flowPair.getLeft().getSourceSwitch().equals(switchId)
133  || flowPair.getRight().getSourceSwitch().equals(switchId)) {
134 
135  MeterEntry entry = new MeterEntry(emptyList(), flowPair.getLeft().getMeterId(),
136  singletonList(new MeterBand(flowPair.getLeft().getBandwidth(), 0, "", 1)), "");
137  result.put(entry.getMeterId(), entry);
138  }
139  });
140 
141  return result;
142  });
143 
144  when(serviceMock.getSwitches())
145  .then((Answer<List<SwitchEntry>>) invocation -> topologyDefinition.getActiveSwitches().stream()
146  .map(sw -> SwitchEntry.builder().switchId(sw.getDpId()).ofVersion(sw.getOfVersion()).build())
147  .collect(toList()));
148 
149  return serviceMock;
150  }
151 
156  ASwitchService serviceMock = mock(ASwitchService.class);
157  List<ASwitchFlow> aswitchFlows = topologyDefinition.getIslsForActiveSwitches().stream()
158  .filter(isl -> isl.getAswitch() != null)
159  .map(isl -> {
160  TopologyDefinition.ASwitch asw = isl.getAswitch();
161  return Arrays.asList(new ASwitchFlow(asw.getInPort(), asw.getOutPort()),
162  new ASwitchFlow(asw.getOutPort(), asw.getInPort()));
163  }).flatMap(List::stream).collect(toList());
164 
165  when(serviceMock.getAllFlows())
166  .thenReturn(aswitchFlows);
167  return serviceMock;
168  }
169 
170  private FlowEntriesMap buildFlowEntries(SwitchId switchId, String switchVersion) {
172 
173  //broadcast verification flow (for all OF versions)
174  FlowEntry flowEntry = buildFlowEntry("flow-0x8000000000000002",
175  FlowMatchField.builder().ethDst("08:ed:02:ef:ff:ff").build(),
176  FlowInstructions.builder().applyActions(
177  FlowApplyActions.builder()
178  .flowOutput("controller")
179  .field(switchId.toMacAddress() + "->eth_dst").build()
180  ).build()
181  );
182  result.put(flowEntry.getCookie(), flowEntry);
183 
184  //define drop flow
185  FlowEntry dropFlow = FlowEntry.builder()
186  .instructions(FlowInstructions.builder().none("drop").build())
187  .priority(1)
188  .cookie("flow-0x8000000000000001")
189  .build();
190  result.put(dropFlow.getCookie(), dropFlow);
191 
192  if ("OF_13".equals(switchVersion)) {
193  //non-broadcast flow for versions 13 and later
194  FlowEntry flowFor13Version = buildFlowEntry("flow-0x8000000000000003",
195  FlowMatchField.builder().ethDst(switchId.toMacAddress()).build(),
196  FlowInstructions.builder().applyActions(
197  FlowApplyActions.builder()
198  .flowOutput("controller")
199  .field(switchId.toMacAddress() + "->eth_dst")
200  .build()
201  ).build()
202  );
203  result.put(flowFor13Version.getCookie(), flowFor13Version);
204  }
205 
206  return result;
207  }
208 
209  private FlowEntry buildFlowEntry(String cookie, FlowMatchField match, FlowInstructions instructions) {
210  return FlowEntry.builder()
211  .instructions(instructions)
212  .match(match)
213  .cookie(cookie)
214  .build();
215  }
216 
221  NorthboundService serviceMock = mock(NorthboundService.class);
222 
223  when(serviceMock.getActiveSwitches())
224  .thenAnswer(invocation -> topologyDefinition.getActiveSwitches().stream()
225  .map(sw -> new SwitchInfoData(sw.getDpId(),
226  SwitchState.ACTIVATED, "", "", "", ""))
227  .collect(toList()));
228 
229  when(serviceMock.getActiveLinks())
230  .thenAnswer(invocation -> topologyDefinition.getIslsForActiveSwitches().stream()
231  .flatMap(link -> Stream.of(
232  new IslInfoData(0,
233  asList(new PathNode(link.getSrcSwitch().getDpId(),
234  link.getSrcPort(), 0),
235  new PathNode(link.getDstSwitch().getDpId(),
236  link.getDstPort(), 1)),
237  link.getMaxBandwidth(), IslChangeType.DISCOVERED, 0),
238  new IslInfoData(0,
239  asList(new PathNode(link.getDstSwitch().getDpId(),
240  link.getDstPort(), 0),
241  new PathNode(link.getSrcSwitch().getDpId(),
242  link.getSrcPort(), 1)),
243  link.getMaxBandwidth(), IslChangeType.DISCOVERED, 0)
244  ))
245  .collect(toList()));
246 
247  when(serviceMock.getAllFlows())
248  .thenReturn(new ArrayList<>(flowPayloads.values()));
249 
250  when(serviceMock.getFlow(any()))
251  .thenAnswer(invocation -> {
252  String flowId = (String) invocation.getArguments()[0];
253  return flowPayloads.containsKey(flowId) ? SerializationUtils.clone(flowPayloads.get(flowId)) : null;
254  });
255 
256  when(serviceMock.getFlowStatus(any()))
257  .thenAnswer(invocation -> {
258  String flowId = (String) invocation.getArguments()[0];
259  return flows.containsKey(flowId) ? new FlowIdStatusPayload(flowId, FlowState.UP) : null;
260  });
261 
262  when(serviceMock.addFlow(any()))
263  .thenAnswer(invocation -> {
264  FlowPayload result = SerializationUtils.clone(((FlowPayload) invocation.getArguments()[0]));
265  result.setLastUpdated(LocalTime.now().toString());
266  result.setStatus(FlowState.ALLOCATED.toString());
267  putFlow(result.getId(), result);
268  return result;
269  });
270 
271  when(serviceMock.updateFlow(any(), any()))
272  .thenAnswer(invocation -> {
273  String flowId = (String) invocation.getArguments()[0];
274  FlowPayload result = SerializationUtils.clone(((FlowPayload) invocation.getArguments()[1]));
275  result.setLastUpdated(LocalTime.now().toString());
276  putFlow(flowId, result);
277  return result;
278  });
279 
280  when(serviceMock.deleteFlow(any()))
281  .thenAnswer(invocation -> {
282  String flowId = (String) invocation.getArguments()[0];
283  flows.remove(flowId);
284  return flowPayloads.remove(flowId);
285  });
286 
287  when(serviceMock.synchronizeSwitchRules(any()))
288  .thenReturn(new RulesSyncResult(emptyList(), emptyList(), emptyList(), emptyList()));
289 
290  when(serviceMock.validateSwitchRules(any()))
291  .thenReturn(new RulesValidationResult(emptyList(), emptyList(), emptyList()));
292 
293  return serviceMock;
294  }
295 
296  private void putFlow(String flowId, FlowPayload flowPayload) {
297  flowPayloads.put(flowId, flowPayload);
298 
299  Flow forwardFlow = FlowPayloadToFlowConverter.buildFlowByFlowPayload(flowPayload);
300  forwardFlow.setMeterId(meterCounter++);
301 
302  Flow reverseFlow = new Flow(forwardFlow);
303  reverseFlow.setSourceSwitch(forwardFlow.getDestinationSwitch());
304  reverseFlow.setSourcePort(forwardFlow.getDestinationPort());
305  reverseFlow.setSourceVlan(forwardFlow.getDestinationVlan());
306  reverseFlow.setDestinationSwitch(forwardFlow.getSourceSwitch());
307  reverseFlow.setDestinationPort(forwardFlow.getSourcePort());
308  reverseFlow.setDestinationVlan(forwardFlow.getSourceVlan());
309 
310  flows.put(flowId, new ImmutablePair<>(forwardFlow, reverseFlow));
311  }
312 
317  TraffExamService serviceMock = mock(TraffExamService.class);
318 
319  when(serviceMock.hostByName(any()))
320  .thenAnswer(invocation -> {
321  String hostName = (String) invocation.getArguments()[0];
322  Host host = mock(Host.class);
323  when(host.getName()).thenReturn(hostName);
324  return host;
325  });
326 
327  when(serviceMock.waitExam(any()))
328  .thenAnswer(invocation -> {
329  Exam exam = (Exam) invocation.getArguments()[0];
330  ExamReport report = mock(ExamReport.class);
331  when(report.hasError()).thenReturn(false);
332  when(report.hasTraffic()).thenReturn(flows.containsKey(exam.getFlow().getId()));
333  when(report.getBandwidth()).thenReturn(new Bandwidth(exam.getFlow().getMaximumBandwidth()));
334  return report;
335  });
336 
337  return serviceMock;
338  }
339 }
Definition: FlowEntry.java:30
Definition: FlowEntry.java:29
Definition: MeterEntry.java:26
list result
Definition: plan-d.py:72
StubServiceFactory(TopologyDefinition topologyDefinition)
List< PathInfoData > getPaths(SwitchId srcSwitch, SwitchId dstSwitch)
RulesValidationResult validateSwitchRules(SwitchId switchId)
def build()
Definition: plan-e.py:73
ImmutablePair< Flow, Flow > getFlow(String flowId)
RulesSyncResult synchronizeSwitchRules(SwitchId switchId)
FlowPayload updateFlow(String flowId, FlowPayload payload)
FlowIdStatusPayload getFlowStatus(String flowId)