Thomas Vachuska

Initial skeleton for the flow space analyzer application.

Change-Id: I1fe9e57a6c66e80a504b98f46fc160aa34003172
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<!--
3 + ~ Copyright 2014 Open Networking Laboratory
4 + ~
5 + ~ Licensed under the Apache License, Version 2.0 (the "License");
6 + ~ you may not use this file except in compliance with the License.
7 + ~ You may obtain a copy of the License at
8 + ~
9 + ~ http://www.apache.org/licenses/LICENSE-2.0
10 + ~
11 + ~ Unless required by applicable law or agreed to in writing, software
12 + ~ distributed under the License is distributed on an "AS IS" BASIS,
13 + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 + ~ See the License for the specific language governing permissions and
15 + ~ limitations under the License.
16 + -->
17 +<project xmlns="http://maven.apache.org/POM/4.0.0"
18 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
19 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
20 + <modelVersion>4.0.0</modelVersion>
21 +
22 + <parent>
23 + <groupId>org.onosproject</groupId>
24 + <artifactId>onos-apps</artifactId>
25 + <version>1.3.0-SNAPSHOT</version>
26 + <relativePath>../pom.xml</relativePath>
27 + </parent>
28 +
29 + <artifactId>onos-app-flowanalyzer</artifactId>
30 + <packaging>bundle</packaging>
31 +
32 + <description>Simple flow space analyzer</description>
33 +
34 + <properties>
35 + <onos.app.name>org.onosproject.flowanalyzer</onos.app.name>
36 + </properties>
37 +
38 + <dependencies>
39 + <dependency>
40 + <groupId>org.osgi</groupId>
41 + <artifactId>org.osgi.compendium</artifactId>
42 + </dependency>
43 + </dependencies>
44 +
45 +</project>
1 +/*
2 + * Copyright 2015 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 +package org.onosproject.flowanalyzer;
17 +
18 +import org.apache.felix.scr.annotations.Activate;
19 +import org.apache.felix.scr.annotations.Component;
20 +import org.apache.felix.scr.annotations.Deactivate;
21 +import org.apache.felix.scr.annotations.Reference;
22 +import org.apache.felix.scr.annotations.ReferenceCardinality;
23 +import org.apache.felix.scr.annotations.Service;
24 +import org.onosproject.net.flow.FlowRuleService;
25 +import org.onosproject.net.host.HostService;
26 +import org.onosproject.net.link.LinkService;
27 +import org.osgi.service.component.ComponentContext;
28 +import org.slf4j.Logger;
29 +
30 +import static org.slf4j.LoggerFactory.getLogger;
31 +
32 +/**
33 + * Simple flow space analyzer app.
34 + */
35 +@Component(immediate = true)
36 +@Service(value = FlowAnalyzer.class)
37 +public class FlowAnalyzer {
38 +
39 + private final Logger log = getLogger(getClass());
40 +
41 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
42 + protected FlowRuleService flowRuleService;
43 +
44 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
45 + protected LinkService linkService;
46 +
47 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
48 + protected HostService hostService;
49 +
50 +
51 + @Activate
52 + public void activate(ComponentContext context) {
53 + log.info("Started");
54 + }
55 +
56 + @Deactivate
57 + public void deactivate() {
58 + log.info("Stopped");
59 + }
60 +
61 +
62 + /**
63 + * ...
64 + */
65 + public void analyze() {
66 + // TODO: implement this
67 + }
68 +
69 +}
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
52 <module>xos-integration</module> 52 <module>xos-integration</module>
53 <module>pcep-api</module> 53 <module>pcep-api</module>
54 <module>olt</module> 54 <module>olt</module>
55 + <module>flowanalyzer</module>
55 </modules> 56 </modules>
56 57
57 <properties> 58 <properties>
......
...@@ -254,6 +254,7 @@ public class FlowObjectiveManager implements FlowObjectiveService { ...@@ -254,6 +254,7 @@ public class FlowObjectiveManager implements FlowObjectiveService {
254 try { 254 try {
255 // Otherwise create it and if it has pipeline behaviour, cache it 255 // Otherwise create it and if it has pipeline behaviour, cache it
256 handler = driverService.createHandler(deviceId); 256 handler = driverService.createHandler(deviceId);
257 + bTime = now();
257 if (!handler.driver().hasBehaviour(Pipeliner.class)) { 258 if (!handler.driver().hasBehaviour(Pipeliner.class)) {
258 log.warn("Pipeline behaviour not supported for device {}", 259 log.warn("Pipeline behaviour not supported for device {}",
259 deviceId); 260 deviceId);
...@@ -265,13 +266,16 @@ public class FlowObjectiveManager implements FlowObjectiveService { ...@@ -265,13 +266,16 @@ public class FlowObjectiveManager implements FlowObjectiveService {
265 } 266 }
266 267
267 driverHandlers.put(deviceId, handler); 268 driverHandlers.put(deviceId, handler);
269 + cTime = now();
268 } 270 }
269 271
270 // Always (re)initialize the pipeline behaviour 272 // Always (re)initialize the pipeline behaviour
271 log.info("Driver {} bound to device {} ... initializing driver", 273 log.info("Driver {} bound to device {} ... initializing driver",
272 handler.driver().name(), deviceId); 274 handler.driver().name(), deviceId);
273 Pipeliner pipeliner = handler.behaviour(Pipeliner.class); 275 Pipeliner pipeliner = handler.behaviour(Pipeliner.class);
276 + dTime = now();
274 pipeliner.init(deviceId, context); 277 pipeliner.init(deviceId, context);
278 + eTime = now();
275 pipeliners.putIfAbsent(deviceId, pipeliner); 279 pipeliners.putIfAbsent(deviceId, pipeliner);
276 } 280 }
277 281
...@@ -282,11 +286,12 @@ public class FlowObjectiveManager implements FlowObjectiveService { ...@@ -282,11 +286,12 @@ public class FlowObjectiveManager implements FlowObjectiveService {
282 switch (event.type()) { 286 switch (event.type()) {
283 case MASTER_CHANGED: 287 case MASTER_CHANGED:
284 log.debug("mastership changed on device {}", event.subject()); 288 log.debug("mastership changed on device {}", event.subject());
285 - long start = startWatch(); 289 + start = now();
286 if (deviceService.isAvailable(event.subject())) { 290 if (deviceService.isAvailable(event.subject())) {
291 + aTime = now();
287 setupPipelineHandler(event.subject()); 292 setupPipelineHandler(event.subject());
288 } 293 }
289 - stopWatch(start); 294 + stopWatch();
290 break; 295 break;
291 case BACKUPS_CHANGED: 296 case BACKUPS_CHANGED:
292 break; 297 break;
...@@ -304,13 +309,14 @@ public class FlowObjectiveManager implements FlowObjectiveService { ...@@ -304,13 +309,14 @@ public class FlowObjectiveManager implements FlowObjectiveService {
304 case DEVICE_ADDED: 309 case DEVICE_ADDED:
305 case DEVICE_AVAILABILITY_CHANGED: 310 case DEVICE_AVAILABILITY_CHANGED:
306 log.debug("Device either added or availability changed {}", 311 log.debug("Device either added or availability changed {}",
307 - event.subject().id()); 312 + event.subject().id());
308 - long start = startWatch(); 313 + start = now();
309 if (deviceService.isAvailable(event.subject().id())) { 314 if (deviceService.isAvailable(event.subject().id())) {
315 + aTime = now();
310 log.debug("Device is now available {}", event.subject().id()); 316 log.debug("Device is now available {}", event.subject().id());
311 setupPipelineHandler(event.subject().id()); 317 setupPipelineHandler(event.subject().id());
312 } 318 }
313 - stopWatch(start); 319 + stopWatch();
314 break; 320 break;
315 case DEVICE_UPDATED: 321 case DEVICE_UPDATED:
316 break; 322 break;
...@@ -332,22 +338,29 @@ public class FlowObjectiveManager implements FlowObjectiveService { ...@@ -332,22 +338,29 @@ public class FlowObjectiveManager implements FlowObjectiveService {
332 338
333 // Temporary mechanism to monitor pipeliner setup time-cost; there are 339 // Temporary mechanism to monitor pipeliner setup time-cost; there are
334 // intermittent time where this takes in excess of 2 seconds. Why? 340 // intermittent time where this takes in excess of 2 seconds. Why?
335 - private long totals = 0, count = 0; 341 + private long start = 0, totals = 0, count = 0;
336 - private static final long LIMIT = 1; 342 + private long aTime, bTime, cTime, dTime, eTime;
343 + private static final long LIMIT = 500;
337 344
338 - private long startWatch() { 345 + private long now() {
339 return System.currentTimeMillis(); 346 return System.currentTimeMillis();
340 } 347 }
341 348
342 - private void stopWatch(long start) { 349 + private void stopWatch() {
343 long duration = System.currentTimeMillis() - start; 350 long duration = System.currentTimeMillis() - start;
344 totals += duration; 351 totals += duration;
345 count += 1; 352 count += 1;
346 if (duration > LIMIT) { 353 if (duration > LIMIT) {
347 - log.info("Pipeline setup took {} ms; avg {} ms", duration, totals / count); 354 + log.info("Pipeline setup took {} ms; avg {} ms; a={}, b={}, c={}, d={}, e={}",
355 + duration, totals / count, diff(aTime), diff(bTime),
356 + diff(cTime), diff(dTime), diff(eTime));
348 } 357 }
349 } 358 }
350 359
360 + private long diff(long bTime) {
361 + return bTime - start;
362 + }
363 +
351 // Processing context for initializing pipeline driver behaviours. 364 // Processing context for initializing pipeline driver behaviours.
352 private class InnerPipelineContext implements PipelinerContext { 365 private class InnerPipelineContext implements PipelinerContext {
353 @Override 366 @Override
......