Brian O'Connor
Committed by Gerrit Code Review

Adding test apps as submodule to apps

Moving election and intent-perf there

Change-Id: Ia71e98438b33d3a1c5c12b08ae98c32930c4bd81
Showing 29 changed files with 1412 additions and 0 deletions
......@@ -43,6 +43,7 @@
<module>routing</module>
<module>routing-api</module>
<module>bgprouter</module>
<module>test</module>
</modules>
<properties>
......
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.onosproject</groupId>
<artifactId>onos-app-samples</artifactId>
<version>1.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>onos-app-election</artifactId>
<packaging>bundle</packaging>
<description>ONOS app leadership election test</description>
<dependencies>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-api</artifactId>
<version>${project.version}</version>
<scope>test</scope>
<classifier>tests</classifier>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-cli</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.karaf.shell</groupId>
<artifactId>org.apache.karaf.shell.console</artifactId>
</dependency>
</dependencies>
</project>
/*
* 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.election;
import static org.slf4j.LoggerFactory.getLogger;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onosproject.cluster.ClusterService;
import org.onosproject.core.CoreService;
import org.onosproject.cluster.ControllerNode;
import org.onosproject.cluster.LeadershipEvent;
import org.onosproject.cluster.LeadershipEventListener;
import org.onosproject.cluster.LeadershipService;
import org.onosproject.core.ApplicationId;
import org.slf4j.Logger;
/**
* Simple application to test leadership election.
*/
@Component(immediate = true)
public class ElectionTest {
private final Logger log = getLogger(getClass());
private static final String ELECTION_APP = "org.onosproject.election";
private ApplicationId appId;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ClusterService clusterService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected LeadershipService leadershipService;
private LeadershipEventListener leadershipEventListener =
new InnerLeadershipEventListener();
private ControllerNode localControllerNode;
@Activate
protected void activate() {
log.info("Election-test app started");
appId = coreService.registerApplication(ELECTION_APP);
localControllerNode = clusterService.getLocalNode();
leadershipService.addListener(leadershipEventListener);
leadershipService.runForLeadership(appId.name());
}
@Deactivate
protected void deactivate() {
leadershipService.withdraw(appId.name());
leadershipService.removeListener(leadershipEventListener);
log.info("Election-test app Stopped");
}
/**
* A listener for Leadership Events.
*/
private class InnerLeadershipEventListener
implements LeadershipEventListener {
@Override
public void event(LeadershipEvent event) {
if (!event.subject().topic().equals(appId.name())) {
return; // Not our topic: ignore
}
//only log what pertains to us
log.debug("Leadership Event: time = {} type = {} event = {}",
event.time(), event.type(), event);
if (!event.subject().leader().equals(
localControllerNode.id())) {
return; // The event is not about this instance: ignore
}
switch (event.type()) {
case LEADER_ELECTED:
log.info("Election-test app leader elected");
break;
case LEADER_BOOTED:
log.info("Election-test app lost election");
break;
case LEADER_REELECTED:
log.debug("Election-test app was re-elected");
break;
default:
break;
}
}
}
}
/*
* 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.election.cli;
import org.onosproject.cluster.NodeId;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.cluster.LeadershipService;
/**
* CLI command to get the current leader for the Election test application.
*/
@Command(scope = "onos", name = "election-test-leader",
description = "Get the current leader for the Election test application")
public class ElectionTestLeaderCommand extends AbstractShellCommand {
private NodeId leader;
private static final String ELECTION_APP = "org.onosproject.election";
@Override
protected void execute() {
LeadershipService service = get(LeadershipService.class);
//print the current leader
leader = service.getLeader(ELECTION_APP);
printLeader(leader);
}
/**
* Prints the leader.
*
* @param leader the leader to print
*/
private void printLeader(NodeId leader) {
if (leader != null) {
print("The current leader for the Election app is %s.", leader);
} else {
print("There is currently no leader elected for the Election app");
}
}
}
/*
* 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.election.cli;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.cluster.LeadershipService;
/**
* CLI command to run for leadership of the Election test application.
*/
@Command(scope = "onos", name = "election-test-run",
description = "Run for leader of the Election test application")
public class ElectionTestRunCommand extends AbstractShellCommand {
private static final String ELECTION_APP = "org.onosproject.election";
@Override
protected void execute() {
LeadershipService service = get(LeadershipService.class);
service.runForLeadership(ELECTION_APP);
//print the current leader
print("Entering leadership elections for the Election app.");
}
}
/*
* 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.election.cli;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.cluster.LeadershipService;
/**
* CLI command to withdraw the local node from leadership election for
* the Election test application.
*/
@Command(scope = "onos", name = "election-test-withdraw",
description = "Withdraw node from leadership election for the Election test application")
public class ElectionTestWithdrawCommand extends AbstractShellCommand {
private static final String ELECTION_APP = "org.onosproject.election";
@Override
protected void execute() {
LeadershipService service = get(LeadershipService.class);
service.withdraw(ELECTION_APP);
//print the current leader
print("Withdrawing from leadership elections for the Election app.");
}
}
/*
* 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.
*/
/**
* Election test command-line handlers.
*/
package org.onosproject.election.cli;
\ No newline at end of file
/*
* 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.
*/
/**
* Sample application for use in various experiments.
*/
package org.onosproject.election;
<!--
~ 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.
-->
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
<command>
<action class="org.onosproject.election.cli.ElectionTestLeaderCommand"/>
</command>
<command>
<action class="org.onosproject.election.cli.ElectionTestRunCommand"/>
</command>
<command>
<action class="org.onosproject.election.cli.ElectionTestWithdrawCommand"/>
</command>
</command-bundle>
</blueprint>
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2015 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.onosproject</groupId>
<artifactId>onos-app-samples</artifactId>
<version>1.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>onos-app-intent-perf</artifactId>
<packaging>bundle</packaging>
<description>ONOS intent perf app bundle</description>
<dependencies>
<dependency>
<groupId>org.apache.karaf.shell</groupId>
<artifactId>org.apache.karaf.shell.console</artifactId>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-cli</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.compendium</artifactId>
</dependency>
<!-- Required for javadoc generation -->
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<descriptor>src/assembly/bin.xml</descriptor>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2015 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.
-->
<app name="org.onosproject.intentperf" origin="ON.Lab" version="1.2.0"
features="onos-app-intent-perf">
<description>Intent performance application</description>
</app>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2015 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.
-->
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<formats>
<format>zip</format>
</formats>
<id>onos</id>
<includeBaseDirectory>false</includeBaseDirectory>
<files>
<file>
<source>src/assembly/app.xml</source>
<destName>app.xml</destName>
</file>
<file>
<source>target/${project.artifactId}-${project.version}.jar</source>
<destName>m2/org/onosproject/${project.artifactId}/${project.version}/${project.artifactId}-${project.version}.jar</destName>
</file>
</files>
</assembly>
\ No newline at end of file
/*
* Copyright 2015 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.intentperf;
import com.google.common.collect.ImmutableList;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onosproject.cluster.ClusterService;
import org.onosproject.cluster.ControllerNode;
import org.onosproject.cluster.NodeId;
import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
import org.onosproject.store.cluster.messaging.ClusterMessage;
import org.onosproject.store.cluster.messaging.ClusterMessageHandler;
import org.onosproject.store.cluster.messaging.MessageSubject;
import org.slf4j.Logger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static org.onlab.util.Tools.groupedThreads;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Collects and distributes performance samples.
*/
@Component(immediate = true)
@Service(value = IntentPerfCollector.class)
public class IntentPerfCollector {
private static final long SAMPLE_TIME_WINDOW_MS = 5_000;
private final Logger log = getLogger(getClass());
private static final int MAX_SAMPLES = 1_000;
private final List<Sample> samples = new LinkedList<>();
private static final MessageSubject SAMPLE = new MessageSubject("intent-perf-sample");
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ClusterCommunicationService communicationService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ClusterService clusterService;
@Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY)
protected IntentPerfUi ui;
// Auxiliary structures used to accrue data for normalized time interval
// across all nodes.
private long newestTime;
private Sample overall;
private Sample current;
private ControllerNode[] nodes;
private Map<NodeId, Integer> nodeToIndex;
private NodeId nodeId;
private ExecutorService messageHandlingExecutor;
@Activate
public void activate() {
nodeId = clusterService.getLocalNode().id();
// TODO: replace with shared executor
messageHandlingExecutor = Executors.newSingleThreadExecutor(
groupedThreads("onos/perf", "message-handler"));
communicationService.addSubscriber(SAMPLE, new InternalSampleCollector(),
messageHandlingExecutor);
nodes = clusterService.getNodes().toArray(new ControllerNode[]{});
Arrays.sort(nodes, (a, b) -> a.id().toString().compareTo(b.id().toString()));
nodeToIndex = new HashMap<>();
for (int i = 0; i < nodes.length; i++) {
nodeToIndex.put(nodes[i].id(), i);
}
clearSamples();
log.info("Started");
}
@Deactivate
public void deactivate() {
messageHandlingExecutor.shutdown();
communicationService.removeSubscriber(SAMPLE);
log.info("Stopped");
}
/**
* Clears all previously accumulated data.
*/
public void clearSamples() {
newestTime = 0;
overall = new Sample(0, nodes.length);
current = new Sample(0, nodes.length);
samples.clear();
}
/**
* Records a sample point of data about intent operation rate.
*
* @param overallRate overall rate
* @param currentRate current rate
*/
public void recordSample(double overallRate, double currentRate) {
long now = System.currentTimeMillis();
addSample(now, nodeId, overallRate, currentRate);
broadcastSample(now, nodeId, overallRate, currentRate);
}
/**
* Returns set of node ids as headers.
*
* @return node id headers
*/
public List<String> getSampleHeaders() {
List<String> headers = new ArrayList<>();
for (ControllerNode node : nodes) {
headers.add(node.id().toString());
}
return headers;
}
/**
* Returns set of all accumulated samples normalized to the local set of
* samples.
*
* @return accumulated samples
*/
public synchronized List<Sample> getSamples() {
return ImmutableList.copyOf(samples);
}
/**
* Returns overall throughput performance for each of the cluster nodes.
*
* @return overall intent throughput
*/
public synchronized Sample getOverall() {
return overall;
}
// Records a new sample to our collection of samples
private synchronized void addSample(long time, NodeId nodeId,
double overallRate, double currentRate) {
Sample fullSample = createCurrentSampleIfNeeded(time);
setSampleData(current, nodeId, currentRate);
setSampleData(overall, nodeId, overallRate);
pruneSamplesIfNeeded();
if (fullSample != null && ui != null) {
ui.reportSample(fullSample);
}
}
private Sample createCurrentSampleIfNeeded(long time) {
Sample oldSample = time - newestTime > SAMPLE_TIME_WINDOW_MS || current.isComplete() ? current : null;
if (oldSample != null) {
newestTime = time;
current = new Sample(time, nodes.length);
if (oldSample.time > 0) {
samples.add(oldSample);
}
}
return oldSample;
}
private void setSampleData(Sample sample, NodeId nodeId, double data) {
Integer index = nodeToIndex.get(nodeId);
if (index != null) {
sample.data[index] = data;
}
}
private void pruneSamplesIfNeeded() {
if (samples.size() > MAX_SAMPLES) {
samples.remove(0);
}
}
// Performance data sample.
static class Sample {
final long time;
final double[] data;
public Sample(long time, int nodeCount) {
this.time = time;
this.data = new double[nodeCount];
Arrays.fill(data, -1);
}
public boolean isComplete() {
for (int i = 0; i < data.length; i++) {
if (data[i] < 0) {
return false;
}
}
return true;
}
}
private void broadcastSample(long time, NodeId nodeId, double overallRate, double currentRate) {
String data = String.format("%d|%f|%f", time, overallRate, currentRate);
communicationService.broadcast(new ClusterMessage(nodeId, SAMPLE, data.getBytes()));
}
private class InternalSampleCollector implements ClusterMessageHandler {
@Override
public void handle(ClusterMessage message) {
String[] fields = new String(message.payload()).split("\\|");
log.debug("Received sample from {}: {}", message.sender(), fields);
addSample(Long.parseLong(fields[0]), message.sender(),
Double.parseDouble(fields[1]), Double.parseDouble(fields[2]));
}
}
}
/*
* Copyright 2015 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.intentperf;
import org.apache.karaf.shell.commands.Command;
import org.apache.karaf.shell.commands.Option;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.intentperf.IntentPerfCollector.Sample;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
* Displays accumulated performance metrics.
*/
@Command(scope = "onos", name = "intent-perf",
description = "Displays accumulated performance metrics")
public class IntentPerfListCommand extends AbstractShellCommand {
@Option(name = "-s", aliases = "--summary", description = "Output just summary",
required = false, multiValued = false)
private boolean summary = false;
@Override
protected void execute() {
if (summary) {
printSummary();
} else {
printSamples();
}
}
private void printSummary() {
IntentPerfCollector collector = get(IntentPerfCollector.class);
List<String> headers = collector.getSampleHeaders();
Sample overall = collector.getOverall();
double total = 0;
print("%12s: %14s", "Node ID", "Overall Rate");
for (int i = 0; i < overall.data.length; i++) {
if (overall.data[i] >= 0) {
print("%12s: %14.2f", headers.get(i), overall.data[i]);
total += overall.data[i];
} else {
print("%12s: %14s", headers.get(i), " ");
}
}
print("%12s: %14.2f", "total", total);
}
private void printSamples() {
IntentPerfCollector collector = get(IntentPerfCollector.class);
List<String> headers = collector.getSampleHeaders();
List<Sample> samples = collector.getSamples();
System.out.print(String.format("%10s ", "Time"));
for (String header : headers) {
System.out.print(String.format("%12s ", header));
}
System.out.println(String.format("%12s", "Total"));
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
for (Sample sample : samples) {
double total = 0;
System.out.print(String.format("%10s ", sdf.format(new Date(sample.time))));
for (int i = 0; i < sample.data.length; i++) {
if (sample.data[i] >= 0) {
System.out.print(String.format("%12.2f ", sample.data[i]));
total += sample.data[i];
} else {
System.out.print(String.format("%12s ", " "));
}
}
System.out.println(String.format("%12.2f", total));
}
}
}
/*
* Copyright 2015 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.intentperf;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
/**
* Starts intent performance test run.
*/
@Command(scope = "onos", name = "intent-perf-start",
description = "Starts intent performance test run")
public class IntentPerfStartCommand extends AbstractShellCommand {
@Override
protected void execute() {
get(IntentPerfInstaller.class).start();
}
}
/*
* Copyright 2015 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.intentperf;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
/**
* Stops intent performance test run.
*/
@Command(scope = "onos", name = "intent-perf-stop",
description = "Stops intent performance test run")
public class IntentPerfStopCommand extends AbstractShellCommand {
@Override
protected void execute() {
get(IntentPerfInstaller.class).stop();
}
}
/*
* Copyright 2015 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.intentperf;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.osgi.ServiceDirectory;
import org.onosproject.intentperf.IntentPerfCollector.Sample;
import org.onosproject.ui.UiConnection;
import org.onosproject.ui.UiExtension;
import org.onosproject.ui.UiExtensionService;
import org.onosproject.ui.UiMessageHandler;
import org.onosproject.ui.UiView;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static java.util.Collections.synchronizedSet;
/**
* Mechanism to stream data to the GUI.
*/
@Component(immediate = true, enabled = false)
public class IntentPerfUi {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected UiExtensionService uiExtensionService;
private final Set<StreamingControl> handlers = synchronizedSet(new HashSet<>());
private List<UiView> views = ImmutableList.of(new UiView("intentPerf", "Intent Performance"));
private UiExtension uiExtension = new UiExtension(views, this::newHandlers,
getClass().getClassLoader());
@Activate
protected void activate() {
uiExtensionService.register(uiExtension);
}
@Deactivate
protected void deactivate() {
uiExtensionService.unregister(uiExtension);
}
/**
* Reports a single sample of performance data.
*
* @param sample performance sample
*/
public void reportSample(Sample sample) {
synchronized (handlers) {
handlers.forEach(h -> h.send(sample));
}
}
// Creates and returns session specific message handler.
private Collection<UiMessageHandler> newHandlers() {
return ImmutableList.of(new StreamingControl());
}
// UI Message handlers for turning on/off reporting to a session.
private class StreamingControl extends UiMessageHandler {
private boolean streamingEnabled = false;
protected StreamingControl() {
super(ImmutableSet.of("intentPerfStart", "intentPerfStop"));
}
@Override
public void process(ObjectNode message) {
streamingEnabled = message.path("event").asText("unknown").equals("initPerfStart");
}
@Override
public void init(UiConnection connection, ServiceDirectory directory) {
super.init(connection, directory);
handlers.add(this);
}
@Override
public void destroy() {
super.destroy();
handlers.remove(this);
}
private void send(Sample sample) {
// FIXME: finish this
ObjectNode sn = mapper.createObjectNode()
.put("time", sample.time);
connection().sendMessage("intentPerf", 0, sn);
}
}
}
/*
* Copyright 2015 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.
*/
/**
* Performance test application that induces steady load on the intent subsystem.
*/
package org.onosproject.intentperf;
\ No newline at end of file
<!--
~ Copyright 2015 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.
-->
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
<command>
<action class="org.onosproject.intentperf.IntentPerfListCommand"/>
</command>
<command>
<action class="org.onosproject.intentperf.IntentPerfStartCommand"/>
</command>
<command>
<action class="org.onosproject.intentperf.IntentPerfStopCommand"/>
</command>
</command-bundle>
</blueprint>
date,value,node
00:55:15,68.38,node1
00:55:15,55.61,node2
00:55:15,74.00,node3
00:55:30,74.20,node1
00:55:30,77.60,node2
00:55:30,74.80,node3
00:55:45,74.60,node1
00:55:45,72.80,node2
00:55:45,77.00,node3
00:56:00,73.60,node1
00:56:00,75.00,node2
00:56:00,76.98,node3
00:56:15,75.82,node1
00:56:15,75.40,node2
00:56:15,76.00,node3
00:56:30,75.60,node1
00:56:30,74.59,node2
00:56:30,74.01,node3
\ No newline at end of file
key,value,date
Group1,37,00:23:00
Group2,12,00:23:00
Group3,46,00:23:00
Group1,32,00:23:05
Group2,19,00:23:05
Group3,42,00:23:05
Group1,45,00:23:10
Group2,16,00:23:10
Group3,44,00:23:10
Group1,24,00:23:15
Group2,52,00:23:15
Group3,64,00:23:15
Group1,34,00:23:20
Group2,62,00:23:20
Group3,74,00:23:20
Group1,34,00:23:25
Group2,62,00:23:25
Group3,74,00:23:25
\ No newline at end of file
/*
* Copyright 2015 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.
*/
/*
ONOS GUI -- Intent Perf View -- CSS file
*/
.light #ov-intentPerf {
color: navy;
}
.dark #ov-intentPerf {
color: #1e5e6f;
}
.dark a {
color: #88c;
}
#ov-intentPerf .msg {
color: darkorange;
}
.light #ov-intentPerf .msg {
color: darkorange;
}
.dark #ov-intentPerf .msg {
color: #904e00;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.browser text {
text-anchor: end;
}
<!--
~ Copyright 2015 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.
-->
<!-- Intent Performance partial HTML -->
<div id="ov-sample">
<h2> Intent Performance View </h2>
<span class="msg">{{ ctrl.message }}</span>
<div id="intent-perf-chart"></div>
</div>
/*
* Copyright 2015 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.
*/
/*
ONOS GUI -- Intent Performance View Module
*/
(function () {
'use strict';
// injected refs
var $log, tbs, flash;
function start() {
//var format = d3.time.format("%m/%d/%y");
var format = d3.time.format("%H:%M:%S");
var samples = [];
var margin = {top: 20, right: 30, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var z = d3.scale.category20c();
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(d3.time.seconds);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var stack = d3.layout.stack()
.offset("zero")
.values(function(d) { return d.values; })
.x(function(d) { return d.date; })
.y(function(d) { return d.value; });
var nest = d3.nest()
.key(function(d) { return d.key; });
var area = d3.svg.area()
.interpolate("cardinal")
.x(function(d) { return x(d.date); })
.y0(function(d) { return y(d.y0); })
.y1(function(d) { return y(d.y0 + d.y); });
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
function fetchData() {
d3.csv("app/view/intentPerf/data.csv", function (data) {
samples = data;
updateGraph();
});
}
function updateGraph() {
samples.forEach(function(d) {
d.date = format.parse(d.date);
d.value = +d.value;
});
var layers = stack(nest.entries(samples));
x.domain(d3.extent(samples, function(d) { return d.date; }));
y.domain([0, d3.max(samples, function(d) { return d.y0 + d.y; })]);
svg.selectAll(".layer")
.data(layers)
.enter().append("path")
.attr("class", "layer")
.attr("d", function(d) { return area(d.values); })
.style("fill", function(d, i) { return z(i); });
svg.select(".x")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.select(".y")
.call(yAxis);
console.log('tick');
}
}
start();
// define the controller
angular.module('ovIntentPerf', ['onosUtil'])
.controller('OvIntentPerfCtrl',
['$scope', '$log', 'ToolbarService', 'FlashService',
function ($scope, _$log_, _tbs_, _flash_) {
var self = this
$log = _$log_;
tbs = _tbs_;
flash = _flash_;
self.message = 'Hey there dudes!';
start();
// Clean up on destroyed scope
$scope.$on('$destroy', function () {
});
$log.log('OvIntentPerfCtrl has been created');
}]);
}());
<link rel="stylesheet" href="app/view/intentPerf/intentPerf.css">
<!DOCTYPE html>
<!--
~ 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.
-->
<html>
<head>
<title>Dev View</title>
<script src="tp/d3.min.js"></script>
<script src="tp/jquery-2.1.1.min.js"></script>
<link rel="stylesheet" href="app/view/intentPerf/intentPerf.css">
</head>
<body>
<div id="intent-perf-chart" style="width: 1024px; height: 800px"></div>
<script src="app/view/intentPerf/intentPerf.js"></script>
</body>
</html>
\ No newline at end of file
<script src="app/view/intentPerf/intentPerf.js"></script>
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2015 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.onosproject</groupId>
<artifactId>onos</artifactId>
<version>1.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>onos-apps-test</artifactId>
<packaging>pom</packaging>
<description>ONOS test applications</description>
<modules>
<module>election</module>
<module>intent-perf</module>
</modules>
</project>