Yuta HIGUCHI
Committed by Brian O'Connor

IntentManager: use IntentStore batch APIs

Change-Id: Ie60f3e53f48fa6acbcaf5cf6837bdef12b36a98d
...@@ -159,6 +159,12 @@ public class SdnIpLeadershipService implements LeadershipService { ...@@ -159,6 +159,12 @@ public class SdnIpLeadershipService implements LeadershipService {
159 } 159 }
160 160
161 @Override 161 @Override
162 + public Map<String, Leadership> getLeaderBoard() {
163 + throw new UnsupportedOperationException("I don't know what to do." +
164 + " I wish you luck.");
165 + }
166 +
167 + @Override
162 public void addListener(LeadershipEventListener listener) { 168 public void addListener(LeadershipEventListener listener) {
163 listenerRegistry.addListener(listener); 169 listenerRegistry.addListener(listener);
164 } 170 }
......
...@@ -15,10 +15,13 @@ ...@@ -15,10 +15,13 @@
15 */ 15 */
16 package org.onlab.onos.cli.net; 16 package org.onlab.onos.cli.net;
17 17
18 +import com.google.common.collect.ArrayListMultimap;
18 import com.google.common.collect.Lists; 19 import com.google.common.collect.Lists;
19 import org.apache.karaf.shell.commands.Argument; 20 import org.apache.karaf.shell.commands.Argument;
20 import org.apache.karaf.shell.commands.Command; 21 import org.apache.karaf.shell.commands.Command;
21 import org.onlab.onos.cli.AbstractShellCommand; 22 import org.onlab.onos.cli.AbstractShellCommand;
23 +import org.onlab.onos.core.ApplicationId;
24 +import org.onlab.onos.core.CoreService;
22 import org.onlab.onos.net.ConnectPoint; 25 import org.onlab.onos.net.ConnectPoint;
23 import org.onlab.onos.net.DeviceId; 26 import org.onlab.onos.net.DeviceId;
24 import org.onlab.onos.net.PortNumber; 27 import org.onlab.onos.net.PortNumber;
...@@ -61,17 +64,27 @@ public class IntentPushTestCommand extends AbstractShellCommand ...@@ -61,17 +64,27 @@ public class IntentPushTestCommand extends AbstractShellCommand
61 required = true, multiValued = false) 64 required = true, multiValued = false)
62 String egressDeviceString = null; 65 String egressDeviceString = null;
63 66
64 - @Argument(index = 2, name = "count", 67 +
65 - description = "Number of intents to push", 68 + @Argument(index = 2, name = "Intents per appId",
66 - required = true, multiValued = false) 69 + description = "Number of intents per appId",
67 - String countString = null; 70 + required = true, multiValued = false)
71 + String intentsPerAppId = null;
72 +
73 + @Argument(index = 3, name = "apps",
74 + description = "Number of appIds",
75 + required = false, multiValued = false)
76 + String appIds = null;
77 +
68 78
69 private IntentService service; 79 private IntentService service;
70 private CountDownLatch latch; 80 private CountDownLatch latch;
71 private long start, end; 81 private long start, end;
82 + private int apps;
83 + private int intentsPerApp;
72 private int count; 84 private int count;
73 private boolean add; 85 private boolean add;
74 86
87 +
75 @Override 88 @Override
76 protected void execute() { 89 protected void execute() {
77 service = get(IntentService.class); 90 service = get(IntentService.class);
...@@ -85,13 +98,18 @@ public class IntentPushTestCommand extends AbstractShellCommand ...@@ -85,13 +98,18 @@ public class IntentPushTestCommand extends AbstractShellCommand
85 PortNumber egressPortNumber = portNumber(getPortNumber(egressDeviceString)); 98 PortNumber egressPortNumber = portNumber(getPortNumber(egressDeviceString));
86 ConnectPoint egress = new ConnectPoint(egressDeviceId, egressPortNumber); 99 ConnectPoint egress = new ConnectPoint(egressDeviceId, egressPortNumber);
87 100
88 - count = Integer.parseInt(countString); 101 + apps = appIds != null ? Integer.parseInt(appIds) : 1;
102 + intentsPerApp = Integer.parseInt(intentsPerAppId);
103 +
104 + count = intentsPerApp * apps;
105 +
89 106
90 service.addListener(this); 107 service.addListener(this);
91 108
109 + ArrayListMultimap<Integer, Intent> operations = generateIntents(ingress, egress);
110 +
92 add = true; 111 add = true;
93 latch = new CountDownLatch(count); 112 latch = new CountDownLatch(count);
94 - List<Intent> operations = generateIntents(ingress, egress);
95 submitIntents(operations); 113 submitIntents(operations);
96 114
97 add = false; 115 add = false;
...@@ -101,36 +119,41 @@ public class IntentPushTestCommand extends AbstractShellCommand ...@@ -101,36 +119,41 @@ public class IntentPushTestCommand extends AbstractShellCommand
101 service.removeListener(this); 119 service.removeListener(this);
102 } 120 }
103 121
104 - private List<Intent> generateIntents(ConnectPoint ingress, ConnectPoint egress) { 122 + private ArrayListMultimap<Integer, Intent> generateIntents(ConnectPoint ingress, ConnectPoint egress) {
105 TrafficSelector.Builder selector = DefaultTrafficSelector.builder() 123 TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
106 .matchEthType(Ethernet.TYPE_IPV4); 124 .matchEthType(Ethernet.TYPE_IPV4);
107 TrafficTreatment treatment = DefaultTrafficTreatment.builder().build(); 125 TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
108 126
109 - List<Intent> intents = Lists.newArrayList(); 127 + ArrayListMultimap<Integer, Intent> intents = ArrayListMultimap.create();
110 - for (int i = 1; i <= count; i++) { 128 + for (int app = 1; app <= apps; app++) {
111 - TrafficSelector s = selector 129 + for (int i = 1; i <= intentsPerApp; i++) {
112 - .matchEthSrc(MacAddress.valueOf(i)) 130 + TrafficSelector s = selector
113 - .build(); 131 + .matchEthSrc(MacAddress.valueOf(i))
114 - intents.add(new PointToPointIntent(appId(), s, treatment, 132 + .build();
115 - ingress, egress)); 133 + intents.put(app, new PointToPointIntent(appId(), s, treatment,
134 + ingress, egress));
116 135
136 + }
117 } 137 }
118 return intents; 138 return intents;
119 } 139 }
120 140
121 - private void submitIntents(List<Intent> intents) { 141 + private void submitIntents(ArrayListMultimap<Integer, Intent> intents) {
122 - IntentOperations.Builder builder = IntentOperations.builder(appId()); 142 + List<IntentOperations> opList = Lists.newArrayList();
123 - for (Intent intent : intents) { 143 + for (Integer app : intents.keySet()) {
124 - if (add) { 144 + IntentOperations.Builder builder = IntentOperations.builder(appId(app));
125 - builder.addSubmitOperation(intent); 145 + for (Intent intent : intents.get(app)) {
126 - } else { 146 + if (add) {
127 - builder.addWithdrawOperation(intent.id()); 147 + builder.addSubmitOperation(intent);
148 + } else {
149 + builder.addWithdrawOperation(intent.id());
150 + }
128 } 151 }
152 + opList.add(builder.build());
129 } 153 }
130 - IntentOperations ops = builder.build();
131 154
132 start = System.currentTimeMillis(); 155 start = System.currentTimeMillis();
133 - service.execute(ops); 156 + opList.forEach(ops -> service.execute(ops));
134 try { 157 try {
135 if (latch.await(100 + count * 200, TimeUnit.MILLISECONDS)) { 158 if (latch.await(100 + count * 200, TimeUnit.MILLISECONDS)) {
136 printResults(count); 159 printResults(count);
...@@ -148,6 +171,16 @@ public class IntentPushTestCommand extends AbstractShellCommand ...@@ -148,6 +171,16 @@ public class IntentPushTestCommand extends AbstractShellCommand
148 print("Time to %s %d intents: %d ms", text, count, delta); 171 print("Time to %s %d intents: %d ms", text, count, delta);
149 } 172 }
150 173
174 +
175 + /**
176 + * Returns application ID for the CLI.
177 + *
178 + * @return command-line application identifier
179 + */
180 + protected ApplicationId appId(Integer id) {
181 + return get(CoreService.class).registerApplication("org.onlab.onos.cli-" + id);
182 + }
183 +
151 /** 184 /**
152 * Extracts the port number portion of the ConnectPoint. 185 * Extracts the port number portion of the ConnectPoint.
153 * 186 *
......
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onlab.onos.cli.net;
17 +
18 +import org.apache.karaf.shell.commands.Command;
19 +import org.onlab.onos.cli.AbstractShellCommand;
20 +import org.onlab.onos.cluster.Leadership;
21 +import org.onlab.onos.cluster.LeadershipService;
22 +
23 +import java.util.Map;
24 +
25 +/**
26 + * Prints the leader for every topic.
27 + */
28 +@Command(scope = "onos", name = "leaders",
29 + description = "Finds the leader for particular topic.")
30 +public class LeaderCommand extends AbstractShellCommand {
31 +
32 + @Override
33 + protected void execute() {
34 + LeadershipService leaderService = get(LeadershipService.class);
35 + Map<String, Leadership> leaderBoard = leaderService.getLeaderBoard();
36 + print("Topic:\t\tLeader");
37 + for (String topic : leaderBoard.keySet()) {
38 + print("%s:\t%s", topic, leaderBoard.get(topic).leader().id());
39 + }
40 + }
41 +
42 +}
...@@ -258,6 +258,9 @@ ...@@ -258,6 +258,9 @@
258 <command> 258 <command>
259 <action class="org.onlab.onos.cli.net.AddFlowsCommand"/> 259 <action class="org.onlab.onos.cli.net.AddFlowsCommand"/>
260 </command> 260 </command>
261 + <command>
262 + <action class="org.onlab.onos.cli.net.LeaderCommand"/>
263 + </command>
261 264
262 <command> 265 <command>
263 <action class="org.onlab.onos.cli.net.WipeOutCommand"/> 266 <action class="org.onlab.onos.cli.net.WipeOutCommand"/>
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
15 */ 15 */
16 package org.onlab.onos.cluster; 16 package org.onlab.onos.cluster;
17 17
18 +import java.util.Map;
19 +
18 /** 20 /**
19 * Service for leader election. 21 * Service for leader election.
20 * Leadership contests are organized around topics. A instance can join the 22 * Leadership contests are organized around topics. A instance can join the
...@@ -43,6 +45,8 @@ public interface LeadershipService { ...@@ -43,6 +45,8 @@ public interface LeadershipService {
43 */ 45 */
44 void withdraw(String path); 46 void withdraw(String path);
45 47
48 + Map<String, Leadership> getLeaderBoard();
49 +
46 /** 50 /**
47 * Registers a event listener to be notified of leadership events. 51 * Registers a event listener to be notified of leadership events.
48 * @param listener listener that will asynchronously notified of leadership events. 52 * @param listener listener that will asynchronously notified of leadership events.
......
...@@ -11,6 +11,7 @@ import java.util.concurrent.Executors; ...@@ -11,6 +11,7 @@ import java.util.concurrent.Executors;
11 import java.util.concurrent.ScheduledExecutorService; 11 import java.util.concurrent.ScheduledExecutorService;
12 import java.util.concurrent.TimeUnit; 12 import java.util.concurrent.TimeUnit;
13 13
14 +import com.google.common.collect.ImmutableMap;
14 import org.apache.felix.scr.annotations.Activate; 15 import org.apache.felix.scr.annotations.Activate;
15 import org.apache.felix.scr.annotations.Component; 16 import org.apache.felix.scr.annotations.Component;
16 import org.apache.felix.scr.annotations.Deactivate; 17 import org.apache.felix.scr.annotations.Deactivate;
...@@ -159,6 +160,11 @@ public class LeadershipManager implements LeadershipService { ...@@ -159,6 +160,11 @@ public class LeadershipManager implements LeadershipService {
159 } 160 }
160 161
161 @Override 162 @Override
163 + public Map<String, Leadership> getLeaderBoard() {
164 + return ImmutableMap.copyOf(leaderBoard);
165 + }
166 +
167 + @Override
162 public void addListener(LeadershipEventListener listener) { 168 public void addListener(LeadershipEventListener listener) {
163 checkArgument(listener != null); 169 checkArgument(listener != null);
164 listeners.add(listener); 170 listeners.add(listener);
......