diff options
Diffstat (limited to 'framework/src/onos/apps/test/intent-perf')
15 files changed, 0 insertions, 1705 deletions
diff --git a/framework/src/onos/apps/test/intent-perf/pom.xml b/framework/src/onos/apps/test/intent-perf/pom.xml deleted file mode 100644 index e0596cc3..00000000 --- a/framework/src/onos/apps/test/intent-perf/pom.xml +++ /dev/null @@ -1,59 +0,0 @@ -<?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-apps-test</artifactId> - <version>1.4.0-rc1</version> - <relativePath>../pom.xml</relativePath> - </parent> - - <artifactId>onos-app-intent-perf</artifactId> - <packaging>bundle</packaging> - - <description>Intent performance test application</description> - - <properties> - <onos.app.name>org.onosproject.intentperf</onos.app.name> - </properties> - - <dependencies> - <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> - <dependency> - <groupId>org.apache.karaf.shell</groupId> - <artifactId>org.apache.karaf.shell.console</artifactId> - </dependency> - <!-- Required for javadoc generation --> - <dependency> - <groupId>org.osgi</groupId> - <artifactId>org.osgi.core</artifactId> - </dependency> - </dependencies> - -</project> diff --git a/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfCollector.java b/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfCollector.java deleted file mode 100644 index cae5455d..00000000 --- a/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfCollector.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * 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 static org.onlab.util.SharedExecutors.getPoolThreadExecutor; -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.MANDATORY_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; - - @Activate - public void activate() { - nodeId = clusterService.getLocalNode().id(); - - communicationService.addSubscriber(SAMPLE, new InternalSampleCollector(), - getPoolThreadExecutor()); - - 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(); - ui.setCollector(this); - log.info("Started"); - } - - @Deactivate - public void deactivate() { - communicationService.removeSubscriber(SAMPLE); - log.info("Stopped"); - } - - /** - * Clears all previously accumulated data. - */ - public synchronized 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(data, SAMPLE, str -> str.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])); - } - } -} diff --git a/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfInstaller.java b/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfInstaller.java deleted file mode 100644 index ad3236e5..00000000 --- a/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfInstaller.java +++ /dev/null @@ -1,596 +0,0 @@ -/* - * 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.ArrayListMultimap; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Multimap; -import com.google.common.collect.Sets; -import org.apache.commons.lang.math.RandomUtils; -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.Modified; -import org.apache.felix.scr.annotations.Property; -import org.apache.felix.scr.annotations.Reference; -import org.apache.felix.scr.annotations.ReferenceCardinality; -import org.apache.felix.scr.annotations.Service; -import org.onlab.packet.MacAddress; -import org.onlab.util.Counter; -import org.onosproject.cfg.ComponentConfigService; -import org.onosproject.cluster.ClusterService; -import org.onosproject.cluster.ControllerNode; -import org.onosproject.cluster.NodeId; -import org.onosproject.core.ApplicationId; -import org.onosproject.core.CoreService; -import org.onosproject.mastership.MastershipService; -import org.onosproject.net.ConnectPoint; -import org.onosproject.net.Device; -import org.onosproject.net.PortNumber; -import org.onosproject.net.device.DeviceService; -import org.onosproject.net.flow.DefaultTrafficSelector; -import org.onosproject.net.flow.DefaultTrafficTreatment; -import org.onosproject.net.flow.TrafficSelector; -import org.onosproject.net.flow.TrafficTreatment; -import org.onosproject.net.intent.Intent; -import org.onosproject.net.intent.IntentEvent; -import org.onosproject.net.intent.IntentListener; -import org.onosproject.net.intent.IntentService; -import org.onosproject.net.intent.Key; -import org.onosproject.net.intent.PartitionService; -import org.onosproject.net.intent.PointToPointIntent; -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.osgi.service.component.ComponentContext; -import org.slf4j.Logger; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Dictionary; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -import static com.google.common.base.Preconditions.checkState; -import static com.google.common.base.Strings.isNullOrEmpty; -import static java.lang.String.format; -import static java.lang.System.currentTimeMillis; -import static org.apache.felix.scr.annotations.ReferenceCardinality.MANDATORY_UNARY; -import static org.onlab.util.Tools.*; -import static org.onosproject.net.intent.IntentEvent.Type.*; -import static org.slf4j.LoggerFactory.getLogger; - -/** - * Application to test sustained intent throughput. - */ -@Component(immediate = true) -@Service(value = IntentPerfInstaller.class) -public class IntentPerfInstaller { - - private final Logger log = getLogger(getClass()); - - private static final int DEFAULT_NUM_WORKERS = 1; - - private static final int DEFAULT_NUM_KEYS = 40000; - private static final int DEFAULT_GOAL_CYCLE_PERIOD = 1000; //ms - - private static final int DEFAULT_NUM_NEIGHBORS = 0; - - private static final int START_DELAY = 5_000; // ms - private static final int REPORT_PERIOD = 1_000; //ms - - private static final String START = "start"; - private static final String STOP = "stop"; - private static final MessageSubject CONTROL = new MessageSubject("intent-perf-ctl"); - - //FIXME add path length - - @Property(name = "numKeys", intValue = DEFAULT_NUM_KEYS, - label = "Number of keys (i.e. unique intents) to generate per instance") - private int numKeys = DEFAULT_NUM_KEYS; - - //TODO implement numWorkers property -// @Property(name = "numThreads", intValue = DEFAULT_NUM_WORKERS, -// label = "Number of installer threads per instance") -// private int numWokers = DEFAULT_NUM_WORKERS; - - @Property(name = "cyclePeriod", intValue = DEFAULT_GOAL_CYCLE_PERIOD, - label = "Goal for cycle period (in ms)") - private int cyclePeriod = DEFAULT_GOAL_CYCLE_PERIOD; - - @Property(name = "numNeighbors", intValue = DEFAULT_NUM_NEIGHBORS, - label = "Number of neighbors to generate intents for") - private int numNeighbors = DEFAULT_NUM_NEIGHBORS; - - @Reference(cardinality = MANDATORY_UNARY) - protected CoreService coreService; - - @Reference(cardinality = MANDATORY_UNARY) - protected IntentService intentService; - - @Reference(cardinality = MANDATORY_UNARY) - protected ClusterService clusterService; - - @Reference(cardinality = MANDATORY_UNARY) - protected DeviceService deviceService; - - @Reference(cardinality = MANDATORY_UNARY) - protected MastershipService mastershipService; - - @Reference(cardinality = MANDATORY_UNARY) - protected PartitionService partitionService; - - @Reference(cardinality = MANDATORY_UNARY) - protected ComponentConfigService configService; - - @Reference(cardinality = MANDATORY_UNARY) - protected IntentPerfCollector sampleCollector; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected ClusterCommunicationService communicationService; - - private ExecutorService messageHandlingExecutor; - - private ExecutorService workers; - private ApplicationId appId; - private Listener listener; - private boolean stopped = true; - - private Timer reportTimer; - - // FIXME this variable isn't shared properly between multiple worker threads - private int lastKey = 0; - - private IntentPerfUi perfUi; - private NodeId nodeId; - private TimerTask reporterTask; - - @Activate - public void activate(ComponentContext context) { - configService.registerProperties(getClass()); - - nodeId = clusterService.getLocalNode().id(); - appId = coreService.registerApplication("org.onosproject.intentperf." + nodeId.toString()); - - // TODO: replace with shared timer - reportTimer = new Timer("onos-intent-perf-reporter"); - workers = Executors.newFixedThreadPool(DEFAULT_NUM_WORKERS, groupedThreads("onos/intent-perf", "worker-%d")); - - // disable flow backups for testing - configService.setProperty("org.onosproject.store.flow.impl.NewDistributedFlowRuleStore", - "backupEnabled", "true"); - - // TODO: replace with shared executor - messageHandlingExecutor = Executors.newSingleThreadExecutor( - groupedThreads("onos/perf", "command-handler")); - - communicationService.addSubscriber(CONTROL, new InternalControl(), - messageHandlingExecutor); - - listener = new Listener(); - intentService.addListener(listener); - - // TODO: investigate why this seems to be necessary for configs to get picked up on initial activation - modify(context); - } - - @Deactivate - public void deactivate() { - stopTestRun(); - - configService.unregisterProperties(getClass(), false); - messageHandlingExecutor.shutdown(); - communicationService.removeSubscriber(CONTROL); - - if (listener != null) { - reportTimer.cancel(); - intentService.removeListener(listener); - listener = null; - reportTimer = null; - } - } - - @Modified - public void modify(ComponentContext context) { - if (context == null) { - logConfig("Reconfigured"); - return; - } - - Dictionary<?, ?> properties = context.getProperties(); - int newNumKeys, newCyclePeriod, newNumNeighbors; - try { - String s = get(properties, "numKeys"); - newNumKeys = isNullOrEmpty(s) ? numKeys : Integer.parseInt(s.trim()); - - s = get(properties, "cyclePeriod"); - newCyclePeriod = isNullOrEmpty(s) ? cyclePeriod : Integer.parseInt(s.trim()); - - s = get(properties, "numNeighbors"); - newNumNeighbors = isNullOrEmpty(s) ? numNeighbors : Integer.parseInt(s.trim()); - - } catch (NumberFormatException | ClassCastException e) { - log.warn("Malformed configuration detected; using defaults", e); - newNumKeys = DEFAULT_NUM_KEYS; - newCyclePeriod = DEFAULT_GOAL_CYCLE_PERIOD; - newNumNeighbors = DEFAULT_NUM_NEIGHBORS; - } - - if (newNumKeys != numKeys || newCyclePeriod != cyclePeriod || newNumNeighbors != numNeighbors) { - numKeys = newNumKeys; - cyclePeriod = newCyclePeriod; - numNeighbors = newNumNeighbors; - logConfig("Reconfigured"); - } - } - - public void start() { - if (stopped) { - stopped = false; - communicationService.broadcast(START, CONTROL, str -> str.getBytes()); - startTestRun(); - } - } - - public void stop() { - if (!stopped) { - communicationService.broadcast(STOP, CONTROL, str -> str.getBytes()); - stopTestRun(); - } - } - - private void logConfig(String prefix) { - log.info("{} with appId {}; numKeys = {}; cyclePeriod = {} ms; numNeighbors={}", - prefix, appId.id(), numKeys, cyclePeriod, numNeighbors); - } - - private void startTestRun() { - sampleCollector.clearSamples(); - - // adjust numNeighbors and generate list of neighbors - numNeighbors = Math.min(clusterService.getNodes().size() - 1, numNeighbors); - - // Schedule reporter task on report period boundary - reporterTask = new ReporterTask(); - reportTimer.scheduleAtFixedRate(reporterTask, - REPORT_PERIOD - currentTimeMillis() % REPORT_PERIOD, - REPORT_PERIOD); - - // Submit workers - stopped = false; - for (int i = 0; i < DEFAULT_NUM_WORKERS; i++) { - workers.submit(new Submitter(createIntents(numKeys, /*FIXME*/ 2, lastKey))); - } - log.info("Started test run"); - } - - private void stopTestRun() { - if (reporterTask != null) { - reporterTask.cancel(); - reporterTask = null; - } - - try { - workers.awaitTermination(5 * cyclePeriod, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - log.warn("Failed to stop worker", e); - } - - sampleCollector.recordSample(0, 0); - sampleCollector.recordSample(0, 0); - stopped = true; - - log.info("Stopped test run"); - } - - private List<NodeId> getNeighbors() { - List<NodeId> nodes = clusterService.getNodes().stream() - .map(ControllerNode::id) - .collect(Collectors.toCollection(ArrayList::new)); - // sort neighbors by id - Collections.sort(nodes, (node1, node2) -> - node1.toString().compareTo(node2.toString())); - // rotate the local node to index 0 - Collections.rotate(nodes, -1 * nodes.indexOf(clusterService.getLocalNode().id())); - log.debug("neighbors (raw): {}", nodes); //TODO remove - // generate the sub-list that will contain local node and selected neighbors - nodes = nodes.subList(0, numNeighbors + 1); - log.debug("neighbors: {}", nodes); //TODO remove - return nodes; - } - - private Intent createIntent(Key key, long mac, NodeId node, Multimap<NodeId, Device> devices) { - // choose a random device for which this node is master - List<Device> deviceList = devices.get(node).stream().collect(Collectors.toList()); - Device device = deviceList.get(RandomUtils.nextInt(deviceList.size())); - - //FIXME we currently ignore the path length and always use the same device - TrafficSelector selector = DefaultTrafficSelector.builder() - .matchEthDst(MacAddress.valueOf(mac)).build(); - TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment(); - ConnectPoint ingress = new ConnectPoint(device.id(), PortNumber.portNumber(1)); - ConnectPoint egress = new ConnectPoint(device.id(), PortNumber.portNumber(2)); - - return PointToPointIntent.builder() - .appId(appId) - .key(key) - .selector(selector) - .treatment(treatment) - .ingressPoint(ingress) - .egressPoint(egress) - .build(); - } - - /** - * Creates a specified number of intents for testing purposes. - * - * @param numberOfKeys number of intents - * @param pathLength path depth - * @param firstKey first key to attempt - * @return set of intents - */ - private Set<Intent> createIntents(int numberOfKeys, int pathLength, int firstKey) { - List<NodeId> neighbors = getNeighbors(); - - Multimap<NodeId, Device> devices = ArrayListMultimap.create(); - deviceService.getAvailableDevices() - .forEach(device -> devices.put(mastershipService.getMasterFor(device.id()), device)); - - // ensure that we have at least one device per neighbor - neighbors.forEach(node -> checkState(devices.get(node).size() > 0, - "There are no devices for {}", node)); - - // TODO pull this outside so that createIntent can use it - // prefix based on node id for keys generated on this instance - long keyPrefix = ((long) clusterService.getLocalNode().ip().getIp4Address().toInt()) << 32; - - int maxKeysPerNode = (int) Math.ceil((double) numberOfKeys / neighbors.size()); - Multimap<NodeId, Intent> intents = ArrayListMultimap.create(); - - for (int count = 0, k = firstKey; count < numberOfKeys; k++) { - Key key = Key.of(keyPrefix + k, appId); - - NodeId leader = partitionService.getLeader(key); - if (!neighbors.contains(leader) || intents.get(leader).size() >= maxKeysPerNode) { - // Bail if we are not sending to this node or we have enough for this node - continue; - } - intents.put(leader, createIntent(key, keyPrefix + k, leader, devices)); - - // Bump up the counter and remember this as the last key used. - count++; - lastKey = k; - if (count % 1000 == 0) { - log.info("Building intents... {} (attempt: {})", count, lastKey); - } - } - checkState(intents.values().size() == numberOfKeys, - "Generated wrong number of intents"); - log.info("Created {} intents", numberOfKeys); - intents.keySet().forEach(node -> log.info("\t{}\t{}", node, intents.get(node).size())); - - return Sets.newHashSet(intents.values()); - } - - // Submits intent operations. - final class Submitter implements Runnable { - - private long lastDuration; - private int lastCount; - - private Set<Intent> intents = Sets.newHashSet(); - private Set<Intent> submitted = Sets.newHashSet(); - private Set<Intent> withdrawn = Sets.newHashSet(); - - private Submitter(Set<Intent> intents) { - this.intents = intents; - lastCount = numKeys / 4; - lastDuration = 1_000; // 1 second - } - - @Override - public void run() { - prime(); - while (!stopped) { - try { - cycle(); - } catch (Exception e) { - log.warn("Exception during cycle", e); - } - } - clear(); - } - - private Iterable<Intent> subset(Set<Intent> intents) { - List<Intent> subset = Lists.newArrayList(intents); - Collections.shuffle(subset); - return subset.subList(0, lastCount); - } - - // Submits the specified intent. - private void submit(Intent intent) { - intentService.submit(intent); - submitted.add(intent); - withdrawn.remove(intent); //TODO could check result here... - } - - // Withdraws the specified intent. - private void withdraw(Intent intent) { - intentService.withdraw(intent); - withdrawn.add(intent); - submitted.remove(intent); //TODO could check result here... - } - - // Primes the cycle. - private void prime() { - int i = 0; - withdrawn.addAll(intents); - for (Intent intent : intents) { - submit(intent); - // only submit half of the intents to start - if (i++ >= intents.size() / 2) { - break; - } - } - } - - private void clear() { - submitted.forEach(this::withdraw); - } - - // Runs a single operation cycle. - private void cycle() { - //TODO consider running without rate adjustment - adjustRates(); - - long start = currentTimeMillis(); - subset(submitted).forEach(this::withdraw); - subset(withdrawn).forEach(this::submit); - long delta = currentTimeMillis() - start; - - if (delta > cyclePeriod * 3 || delta < 0) { - log.warn("Cycle took {} ms", delta); - } - - int difference = cyclePeriod - (int) delta; - if (difference > 0) { - delay(difference); - } - - lastDuration = delta; - } - - int cycleCount = 0; - - private void adjustRates() { - - int addDelta = Math.max(1000 - cycleCount, 10); - double multRatio = Math.min(0.8 + cycleCount * 0.0002, 0.995); - - //FIXME need to iron out the rate adjustment - //FIXME we should taper the adjustments over time - //FIXME don't just use the lastDuration, take an average - if (++cycleCount % 5 == 0) { //TODO: maybe use a timer (we should do this every 5-10 sec) - if (listener.requestThroughput() - listener.processedThroughput() <= 2000 && //was 500 - lastDuration <= cyclePeriod) { - lastCount = Math.min(lastCount + addDelta, intents.size() / 2); - } else { - lastCount *= multRatio; - } - log.info("last count: {}, last duration: {} ms (sub: {} vs inst: {})", - lastCount, lastDuration, listener.requestThroughput(), listener.processedThroughput()); - } - - } - } - - // Event listener to monitor throughput. - final class Listener implements IntentListener { - - private final Counter runningTotal = new Counter(); - private volatile Map<IntentEvent.Type, Counter> counters; - - private volatile double processedThroughput = 0; - private volatile double requestThroughput = 0; - - public Listener() { - counters = initCounters(); - } - - private Map<IntentEvent.Type, Counter> initCounters() { - Map<IntentEvent.Type, Counter> map = Maps.newHashMap(); - for (IntentEvent.Type type : IntentEvent.Type.values()) { - map.put(type, new Counter()); - } - return map; - } - - public double processedThroughput() { - return processedThroughput; - } - - public double requestThroughput() { - return requestThroughput; - } - - @Override - public void event(IntentEvent event) { - if (event.subject().appId().equals(appId)) { - counters.get(event.type()).add(1); - } - } - - public void report() { - Map<IntentEvent.Type, Counter> reportCounters = counters; - counters = initCounters(); - - // update running total and latest throughput - Counter installed = reportCounters.get(INSTALLED); - Counter withdrawn = reportCounters.get(WITHDRAWN); - processedThroughput = installed.throughput() + withdrawn.throughput(); - runningTotal.add(installed.total() + withdrawn.total()); - - Counter installReq = reportCounters.get(INSTALL_REQ); - Counter withdrawReq = reportCounters.get(WITHDRAW_REQ); - requestThroughput = installReq.throughput() + withdrawReq.throughput(); - - // build the string to report - StringBuilder stringBuilder = new StringBuilder(); - for (IntentEvent.Type type : IntentEvent.Type.values()) { - Counter counter = reportCounters.get(type); - stringBuilder.append(format("%s=%.2f;", type, counter.throughput())); - } - log.info("Throughput: OVERALL={}; CURRENT={}; {}", - format("%.2f", runningTotal.throughput()), - format("%.2f", processedThroughput), - stringBuilder); - - sampleCollector.recordSample(runningTotal.throughput(), - processedThroughput); - } - } - - private class InternalControl implements ClusterMessageHandler { - @Override - public void handle(ClusterMessage message) { - String cmd = new String(message.payload()); - log.info("Received command {}", cmd); - if (cmd.equals(START)) { - startTestRun(); - } else { - stopTestRun(); - } - } - } - - private class ReporterTask extends TimerTask { - @Override - public void run() { - //adjustRates(); // FIXME we currently adjust rates in the cycle thread - listener.report(); - } - } - -} diff --git a/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfListCommand.java b/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfListCommand.java deleted file mode 100644 index a5567125..00000000 --- a/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfListCommand.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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)); - } - } - -} diff --git a/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfStartCommand.java b/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfStartCommand.java deleted file mode 100644 index 35491539..00000000 --- a/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfStartCommand.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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(); - } - -} diff --git a/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfStopCommand.java b/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfStopCommand.java deleted file mode 100644 index ac45cd82..00000000 --- a/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfStopCommand.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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(); - } - -} diff --git a/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfUi.java b/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfUi.java deleted file mode 100644 index a44ead57..00000000 --- a/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfUi.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * 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.ArrayNode; -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.apache.felix.scr.annotations.Service; -import org.onlab.osgi.ServiceDirectory; -import org.onosproject.intentperf.IntentPerfCollector.Sample; -import org.onosproject.ui.RequestHandler; -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; -import static org.onosproject.ui.UiView.Category.OTHER; - -/** - * Mechanism to stream data to the GUI. - */ -@Component(immediate = true, enabled = true) -@Service(value = IntentPerfUi.class) -public class IntentPerfUi { - - private static final String INTENT_PERF_START = "intentPerfStart"; - private static final String INTENT_PERF_STOP = "intentPerfStop"; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected UiExtensionService uiExtensionService; - - private final Set<StreamingControl> handlers = synchronizedSet(new HashSet<>()); - - private List<UiView> views = ImmutableList.of( - new UiView(OTHER, "intentPerf", "Intent Performance") - ); - - private UiExtension uiExtension = - new UiExtension.Builder(getClass().getClassLoader(), views) - .messageHandlerFactory(this::newHandlers) - .build(); - - private IntentPerfCollector collector; - - @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)); - } - } - - /** - * Binds the sample collector. - * - * @param collector list of headers for future samples - */ - public void setCollector(IntentPerfCollector collector) { - this.collector = collector; - } - - // 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; - - @Override - protected Collection<RequestHandler> createRequestHandlers() { - return ImmutableSet.of( - new IntentPerfStart(), - new IntentPerfStop() - ); - } - - @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) { - if (streamingEnabled) { - connection().sendMessage("intentPerfSample", 0, sampleNode(sample)); - } - } - - - private ObjectNode sampleNode(Sample sample) { - ObjectNode sampleNode = objectNode(); - ArrayNode an = arrayNode(); - sampleNode.put("time", sample.time); - sampleNode.set("data", an); - - for (double d : sample.data) { - an.add(d); - } - return sampleNode; - } - - // ====================================================================== - - private final class IntentPerfStart extends RequestHandler { - - private IntentPerfStart() { - super(INTENT_PERF_START); - } - - @Override - public void process(long sid, ObjectNode payload) { - streamingEnabled = true; - sendInitData(); - } - - private void sendInitData() { - ObjectNode rootNode = MAPPER.createObjectNode(); - ArrayNode an = MAPPER.createArrayNode(); - ArrayNode sn = MAPPER.createArrayNode(); - rootNode.set("headers", an); - rootNode.set("samples", sn); - - collector.getSampleHeaders().forEach(an::add); - collector.getSamples().forEach(s -> sn.add(sampleNode(s))); - sendMessage("intentPerfInit", 0, rootNode); - } - } - - // ====================================================================== - - private final class IntentPerfStop extends RequestHandler { - - private IntentPerfStop() { - super(INTENT_PERF_STOP); - } - - @Override - public void process(long sid, ObjectNode payload) { - streamingEnabled = false; - } - } - - } - -} diff --git a/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/package-info.java b/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/package-info.java deleted file mode 100644 index 75d40e49..00000000 --- a/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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 diff --git a/framework/src/onos/apps/test/intent-perf/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/framework/src/onos/apps/test/intent-perf/src/main/resources/OSGI-INF/blueprint/shell-config.xml deleted file mode 100644 index fc46d1de..00000000 --- a/framework/src/onos/apps/test/intent-perf/src/main/resources/OSGI-INF/blueprint/shell-config.xml +++ /dev/null @@ -1,28 +0,0 @@ -<!-- - ~ 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> diff --git a/framework/src/onos/apps/test/intent-perf/src/main/resources/app/view/intentPerf/intentPerf.css b/framework/src/onos/apps/test/intent-perf/src/main/resources/app/view/intentPerf/intentPerf.css deleted file mode 100644 index 15e95d5e..00000000 --- a/framework/src/onos/apps/test/intent-perf/src/main/resources/app/view/intentPerf/intentPerf.css +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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 - */ - -svg { - font: 12px sans-serif; -} - -.line,.lineTotal { - fill: none; - stroke-width: 2px; -} - -.axis path, -.axis line { - fill: none; - stroke-width: 2px; - shape-rendering: crispEdges; -} - -.light .axis path, -.light .axis line, -.light .lineTotal { - stroke: #333; -} - -.light .axis text { - fill: #333; -} - -.dark .axis path, -.dark .axis line, -.dark .lineTotal { - stroke: #eee; -} - -.dark .axis text { - fill: #eee; -} diff --git a/framework/src/onos/apps/test/intent-perf/src/main/resources/app/view/intentPerf/intentPerf.html b/framework/src/onos/apps/test/intent-perf/src/main/resources/app/view/intentPerf/intentPerf.html deleted file mode 100644 index 6cdbc665..00000000 --- a/framework/src/onos/apps/test/intent-perf/src/main/resources/app/view/intentPerf/intentPerf.html +++ /dev/null @@ -1,26 +0,0 @@ -<!-- - ~ 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-intentPerf"> - <h2> Intent Performance View </h2> - - <div id="intent-perf-chart" - resize - ng-style="resizeWithOffset(56, 12)" - notifier="ctrl.notifyResize()"> - </div> -</div> diff --git a/framework/src/onos/apps/test/intent-perf/src/main/resources/app/view/intentPerf/intentPerf.js b/framework/src/onos/apps/test/intent-perf/src/main/resources/app/view/intentPerf/intentPerf.js deleted file mode 100644 index 94304c73..00000000 --- a/framework/src/onos/apps/test/intent-perf/src/main/resources/app/view/intentPerf/intentPerf.js +++ /dev/null @@ -1,307 +0,0 @@ -/* - * 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, ts, wss, sus, flash, fs, mast; - - // internal state - var handlerMap, - openListener, - theSample = [], - graph; - - // ========================== - - function createGraph(h, samples) { - var stopped = false, - n = 243, - duration = 750, - now = new Date(Date.now() - duration), - headers = h, - data = []; - - var dim = fs.windowSize(mast.mastHeight()); - var margin, width, height, x, y; - var svg, axis; - - var lines = [], - paths = []; - - var transition = d3.select({}).transition() - .duration(duration) - .ease("linear"); - - svg = d3.select("#intent-perf-chart").append("p").append("svg") - .attr("id", "intent-perf-svg") - .append("g") - .attr("id", "intent-perf-svg-g"); - - svg.append("defs").append("clipPath") - .attr("id", "intent-perf-clip") - .append("rect"); - - axis = svg.append("g") - .attr("class", "x axis") - .attr("id", "intent-perf-x"); - - svg.append("g").attr("class", "y axis") - .attr("id", "intent-perf-yl"); - - svg.append("g") - .attr("class", "y axis") - .attr("id", "intent-perf-yr"); - - resize(dim); - - headers.forEach(function (h, li) { - // Prime the data to match the headers and zero it out. - data[li] = d3.range(n).map(function() { return 0 }); - - if (li < headers.length - 1) { - samples.forEach(function (s, i) { - var di = dataIndex(s.time); - if (di >= 0) { - data[li][di] = s.data[li]; - } - }); - - data[li].forEach(function (d, i) { - if (!d && i > 0) { - data[li][i] = data[li][i - 1]; - } - }); - } else { - data[li].forEach(function (t, i) { - for (var si = 0; si < headers.length - 1; si++) { - data[li][i] = data[si][i]; - } - }); - } - - // Create the lines - lines[li] = d3.svg.line() - .interpolate("basis") - .x(function(d, i) { return x(now - (n - 1 - i) * duration); }) - .y(function(d, i) { return y(d); }); - - // Create the SVG paths - paths[li] = svg.append("g") - .attr("clip-path", "url(#intent-perf-clip)") - .append("path") - .datum(function () { return data[li]; }) - .attr("id", "line" + li); - - if (li < headers.length - 1) { - paths[li].attr("class", "line").style("stroke", lineColor(li)); - } else { - paths[li].attr("class", "lineTotal"); - } - }); - - function dataIndex(time) { - var delta = now.getTime() - time; - var di = Math.round(n - 2 - (delta / duration)); - // $log.info('now=' + now.getTime() + '; then=' + time + '; delta=' + delta + '; di=' + di + ';'); - return di >= n || di < 0 ? -1 : di; - } - - function lineColor(li) { - return sus.cat7().getColor(li, false, ts.theme()); - } - - function tick() { - if (stopped) { - return; - } - - transition = transition.each(function() { - // update the domains - now = new Date(); - x.domain([now - (n - 2) * duration, now - duration]); - - data.forEach(function (d, li) { - // push the new most recent sample onto the back - d.push(theSample[li]); - - // redraw the line and slide it left - paths[li].attr("d", lines[li]).attr("transform", null); - paths[li].transition() - .attr("transform", "translate(" + x(now - (n - 1) * duration) + ")"); - - // pop the old data point off the front - d.shift(); - }); - - // slide the x-axis left - axis.call(x.axis); - }).transition().each("start", tick); - } - - function start() { - stopped = false; - headers.forEach(function (h, li) { - theSample[li] = data[li][n-1]; - }); - tick(); - } - - function stop() { - headers.forEach(function (h, li) { - theSample[li] = 0; - }); - // Schedule delayed stop to allow 0s to render. - setTimeout(function () { stopped = true; }, 1000); - } - - function resize(dim) { - margin = {top: 20, right: 90, bottom: 20, left: 70}; - width = dim.width - margin.right - margin.left; - height = 480 - margin.top - margin.bottom; - - x = d3.time.scale() - .domain([now - (n - 2) * duration, now - duration]) - .range([0, width]); - - y = d3.scale.linear() - .domain([0, 200000]) - .range([height, 0]); - - d3.select("#intent-perf-svg") - .attr("width", width + margin.left + margin.right) - .attr("height", height + margin.top + margin.bottom); - d3.select("#intent-perf-svg-g") - .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); - - d3.select("#intent-perf-clip rect") - .attr("width", width) - .attr("height", height); - - d3.select("#intent-perf-x") - .attr("transform", "translate(0," + height + ")") - .call(x.axis = d3.svg.axis().scale(x).orient("bottom")); - - d3.select("#intent-perf-yl") - .call(d3.svg.axis().scale(y).orient("left")) - d3.select("#intent-perf-yr") - .attr("transform", "translate(" + width + " ,0)") - .call(d3.svg.axis().scale(y).orient("right")) - } - - return { - start: start, - stop: stop, - resize: resize - }; - } - - - function wsOpen(host, url) { - $log.debug('IntentPerf: web socket open - cluster node:', host, 'URL:', url); - // Request batch of initial data from the new server - wss.sendEvent('intentPerfStart'); - } - - function createAndInitGraph(d) { - if (!graph) { - d.headers.push("total"); - graph = createGraph(d.headers, d.samples); - } - graph.start(); - } - - function graphResized(dim) { - $log.info("Resized: " + dim.width + "x" + dim.height); - if (graph) { - graph.resize(dim); - } - } - - function recordSample(sample) { - var total = 0; - sample.data.forEach(function (d, i) { - theSample[i] = d; - total = total + d; - }); - theSample[sample.data.length] = total; - } - - function createHandlerMap() { - handlerMap = { - intentPerfInit: createAndInitGraph, - intentPerfSample: recordSample - }; - } - - // define the controller - - angular.module('ovIntentPerf', ['onosUtil']) - .controller('OvIntentPerfCtrl', - ['$scope', '$log', 'ToolbarService', 'WebSocketService', - 'ThemeService', 'FlashService', 'SvgUtilService', 'FnService', - 'MastService', - - function ($scope, _$log_, _tbs_, _wss_, _ts_, _flash_, _sus_, _fs_, _mast_) { - var self = this; - - $log = _$log_; - tbs = _tbs_; - wss = _wss_; - ts = _ts_; - flash = _flash_; - sus = _sus_; - fs = _fs_; - mast = _mast_; - - createHandlerMap(); - - self.notifyResize = function () { - graphResized(fs.windowSize(mast.mastHeight())); - }; - - function start() { - openListener = wss.addOpenListener(wsOpen); - wss.bindHandlers(handlerMap); - wss.sendEvent('intentPerfStart'); - $log.debug('intentPerf comms started'); - } - - function stop() { - graph.stop(); - wss.sendEvent('intentPerfStop'); - wss.unbindHandlers(handlerMap); - wss.removeOpenListener(openListener); - openListener = null; - graph = null; - $log.debug('intentPerf comms stopped'); - } - - // Cleanup on destroyed scope.. - $scope.$on('$destroy', function () { - $log.log('OvIntentPerfCtrl is saying Buh-Bye!'); - stop(); - }); - - $log.log('OvIntentPerfCtrl has been created'); - - start(); - }]); -}()); diff --git a/framework/src/onos/apps/test/intent-perf/src/main/resources/css.html b/framework/src/onos/apps/test/intent-perf/src/main/resources/css.html deleted file mode 100644 index 06dd7e8b..00000000 --- a/framework/src/onos/apps/test/intent-perf/src/main/resources/css.html +++ /dev/null @@ -1 +0,0 @@ -<link rel="stylesheet" href="app/view/intentPerf/intentPerf.css"> diff --git a/framework/src/onos/apps/test/intent-perf/src/main/resources/dev.html b/framework/src/onos/apps/test/intent-perf/src/main/resources/dev.html deleted file mode 100644 index d0b59f46..00000000 --- a/framework/src/onos/apps/test/intent-perf/src/main/resources/dev.html +++ /dev/null @@ -1,27 +0,0 @@ -<!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> - <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 diff --git a/framework/src/onos/apps/test/intent-perf/src/main/resources/js.html b/framework/src/onos/apps/test/intent-perf/src/main/resources/js.html deleted file mode 100644 index e8bf551f..00000000 --- a/framework/src/onos/apps/test/intent-perf/src/main/resources/js.html +++ /dev/null @@ -1 +0,0 @@ -<script src="app/view/intentPerf/intentPerf.js"></script> |