Yuta HIGUCHI
Committed by Brian O'Connor

IntentManager: use IntentStore batch APIs

Change-Id: Ie60f3e53f48fa6acbcaf5cf6837bdef12b36a98d
......@@ -159,6 +159,12 @@ public class SdnIpLeadershipService implements LeadershipService {
}
@Override
public Map<String, Leadership> getLeaderBoard() {
throw new UnsupportedOperationException("I don't know what to do." +
" I wish you luck.");
}
@Override
public void addListener(LeadershipEventListener listener) {
listenerRegistry.addListener(listener);
}
......
......@@ -15,10 +15,13 @@
*/
package org.onlab.onos.cli.net;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onlab.onos.cli.AbstractShellCommand;
import org.onlab.onos.core.ApplicationId;
import org.onlab.onos.core.CoreService;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.PortNumber;
......@@ -61,17 +64,27 @@ public class IntentPushTestCommand extends AbstractShellCommand
required = true, multiValued = false)
String egressDeviceString = null;
@Argument(index = 2, name = "count",
description = "Number of intents to push",
required = true, multiValued = false)
String countString = null;
@Argument(index = 2, name = "Intents per appId",
description = "Number of intents per appId",
required = true, multiValued = false)
String intentsPerAppId = null;
@Argument(index = 3, name = "apps",
description = "Number of appIds",
required = false, multiValued = false)
String appIds = null;
private IntentService service;
private CountDownLatch latch;
private long start, end;
private int apps;
private int intentsPerApp;
private int count;
private boolean add;
@Override
protected void execute() {
service = get(IntentService.class);
......@@ -85,13 +98,18 @@ public class IntentPushTestCommand extends AbstractShellCommand
PortNumber egressPortNumber = portNumber(getPortNumber(egressDeviceString));
ConnectPoint egress = new ConnectPoint(egressDeviceId, egressPortNumber);
count = Integer.parseInt(countString);
apps = appIds != null ? Integer.parseInt(appIds) : 1;
intentsPerApp = Integer.parseInt(intentsPerAppId);
count = intentsPerApp * apps;
service.addListener(this);
ArrayListMultimap<Integer, Intent> operations = generateIntents(ingress, egress);
add = true;
latch = new CountDownLatch(count);
List<Intent> operations = generateIntents(ingress, egress);
submitIntents(operations);
add = false;
......@@ -101,36 +119,41 @@ public class IntentPushTestCommand extends AbstractShellCommand
service.removeListener(this);
}
private List<Intent> generateIntents(ConnectPoint ingress, ConnectPoint egress) {
private ArrayListMultimap<Integer, Intent> generateIntents(ConnectPoint ingress, ConnectPoint egress) {
TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
.matchEthType(Ethernet.TYPE_IPV4);
TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
List<Intent> intents = Lists.newArrayList();
for (int i = 1; i <= count; i++) {
TrafficSelector s = selector
.matchEthSrc(MacAddress.valueOf(i))
.build();
intents.add(new PointToPointIntent(appId(), s, treatment,
ingress, egress));
ArrayListMultimap<Integer, Intent> intents = ArrayListMultimap.create();
for (int app = 1; app <= apps; app++) {
for (int i = 1; i <= intentsPerApp; i++) {
TrafficSelector s = selector
.matchEthSrc(MacAddress.valueOf(i))
.build();
intents.put(app, new PointToPointIntent(appId(), s, treatment,
ingress, egress));
}
}
return intents;
}
private void submitIntents(List<Intent> intents) {
IntentOperations.Builder builder = IntentOperations.builder(appId());
for (Intent intent : intents) {
if (add) {
builder.addSubmitOperation(intent);
} else {
builder.addWithdrawOperation(intent.id());
private void submitIntents(ArrayListMultimap<Integer, Intent> intents) {
List<IntentOperations> opList = Lists.newArrayList();
for (Integer app : intents.keySet()) {
IntentOperations.Builder builder = IntentOperations.builder(appId(app));
for (Intent intent : intents.get(app)) {
if (add) {
builder.addSubmitOperation(intent);
} else {
builder.addWithdrawOperation(intent.id());
}
}
opList.add(builder.build());
}
IntentOperations ops = builder.build();
start = System.currentTimeMillis();
service.execute(ops);
opList.forEach(ops -> service.execute(ops));
try {
if (latch.await(100 + count * 200, TimeUnit.MILLISECONDS)) {
printResults(count);
......@@ -148,6 +171,16 @@ public class IntentPushTestCommand extends AbstractShellCommand
print("Time to %s %d intents: %d ms", text, count, delta);
}
/**
* Returns application ID for the CLI.
*
* @return command-line application identifier
*/
protected ApplicationId appId(Integer id) {
return get(CoreService.class).registerApplication("org.onlab.onos.cli-" + id);
}
/**
* Extracts the port number portion of the ConnectPoint.
*
......
/*
* 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.onlab.onos.cli.net;
import org.apache.karaf.shell.commands.Command;
import org.onlab.onos.cli.AbstractShellCommand;
import org.onlab.onos.cluster.Leadership;
import org.onlab.onos.cluster.LeadershipService;
import java.util.Map;
/**
* Prints the leader for every topic.
*/
@Command(scope = "onos", name = "leaders",
description = "Finds the leader for particular topic.")
public class LeaderCommand extends AbstractShellCommand {
@Override
protected void execute() {
LeadershipService leaderService = get(LeadershipService.class);
Map<String, Leadership> leaderBoard = leaderService.getLeaderBoard();
print("Topic:\t\tLeader");
for (String topic : leaderBoard.keySet()) {
print("%s:\t%s", topic, leaderBoard.get(topic).leader().id());
}
}
}
......@@ -258,6 +258,9 @@
<command>
<action class="org.onlab.onos.cli.net.AddFlowsCommand"/>
</command>
<command>
<action class="org.onlab.onos.cli.net.LeaderCommand"/>
</command>
<command>
<action class="org.onlab.onos.cli.net.WipeOutCommand"/>
......
......@@ -15,6 +15,8 @@
*/
package org.onlab.onos.cluster;
import java.util.Map;
/**
* Service for leader election.
* Leadership contests are organized around topics. A instance can join the
......@@ -43,6 +45,8 @@ public interface LeadershipService {
*/
void withdraw(String path);
Map<String, Leadership> getLeaderBoard();
/**
* Registers a event listener to be notified of leadership events.
* @param listener listener that will asynchronously notified of leadership events.
......
......@@ -11,6 +11,7 @@ import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import com.google.common.collect.ImmutableMap;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
......@@ -159,6 +160,11 @@ public class LeadershipManager implements LeadershipService {
}
@Override
public Map<String, Leadership> getLeaderBoard() {
return ImmutableMap.copyOf(leaderBoard);
}
@Override
public void addListener(LeadershipEventListener listener) {
checkArgument(listener != null);
listeners.add(listener);
......