Brian Stanke
Committed by Gerrit Code Review

ONOS-2184 - Initial implementation of Virtual network Intent service.

Change-Id: I03103b4eca797cd32480fbd0e3b4cf0385b50ef2
Showing 24 changed files with 2078 additions and 55 deletions
...@@ -2,6 +2,7 @@ COMPILE_DEPS = [ ...@@ -2,6 +2,7 @@ COMPILE_DEPS = [
2 '//lib:CORE_DEPS', 2 '//lib:CORE_DEPS',
3 '//lib:org.apache.karaf.shell.console', 3 '//lib:org.apache.karaf.shell.console',
4 '//incubator/api:onos-incubator-api', 4 '//incubator/api:onos-incubator-api',
5 + '//incubator/net:onos-incubator-net',
5 '//utils/rest:onlab-rest', 6 '//utils/rest:onlab-rest',
6 '//core/common:onos-core-common', 7 '//core/common:onos-core-common',
7 ] 8 ]
......
1 +/*
2 + * Copyright 2016-present 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 +
17 +package org.onosproject.cli.net.vnet;
18 +
19 +import org.apache.karaf.shell.commands.Argument;
20 +import org.apache.karaf.shell.commands.Command;
21 +import org.onosproject.cli.net.ConnectivityIntentCommand;
22 +import org.onosproject.incubator.net.virtual.NetworkId;
23 +import org.onosproject.incubator.net.virtual.VirtualNetworkIntent;
24 +import org.onosproject.incubator.net.virtual.VirtualNetworkService;
25 +import org.onosproject.net.ConnectPoint;
26 +import org.onosproject.net.flow.TrafficSelector;
27 +import org.onosproject.net.flow.TrafficTreatment;
28 +import org.onosproject.net.intent.Constraint;
29 +import org.onosproject.net.intent.Intent;
30 +import org.onosproject.net.intent.IntentService;
31 +
32 +import java.util.List;
33 +
34 +/**
35 + * Installs virtual network intents.
36 + */
37 +@Command(scope = "onos", name = "add-vnet-intent",
38 + description = "Installs virtual network connectivity intent")
39 +public class VirtualNetworkIntentCreateCommand extends ConnectivityIntentCommand {
40 +
41 + @Argument(index = 0, name = "networkId", description = "Network ID",
42 + required = true, multiValued = false)
43 + Long networkId = null;
44 +
45 + @Argument(index = 1, name = "ingressDevice",
46 + description = "Ingress Device/Port Description",
47 + required = true, multiValued = false)
48 + String ingressDeviceString = null;
49 +
50 + @Argument(index = 2, name = "egressDevice",
51 + description = "Egress Device/Port Description",
52 + required = true, multiValued = false)
53 + String egressDeviceString = null;
54 +
55 + @Override
56 + protected void execute() {
57 + VirtualNetworkService service = get(VirtualNetworkService.class);
58 + IntentService virtualNetworkIntentService = service.get(NetworkId.networkId(networkId), IntentService.class);
59 +
60 + ConnectPoint ingress = ConnectPoint.deviceConnectPoint(ingressDeviceString);
61 + ConnectPoint egress = ConnectPoint.deviceConnectPoint(egressDeviceString);
62 +
63 + TrafficSelector selector = buildTrafficSelector();
64 + TrafficTreatment treatment = buildTrafficTreatment();
65 +
66 + List<Constraint> constraints = buildConstraints();
67 +
68 + Intent intent = VirtualNetworkIntent.builder()
69 + .networkId(NetworkId.networkId(networkId))
70 + .appId(appId())
71 + .key(key())
72 + .selector(selector)
73 + .treatment(treatment)
74 + .ingressPoint(ingress)
75 + .egressPoint(egress)
76 + .constraints(constraints)
77 + .priority(priority())
78 + .build();
79 + virtualNetworkIntentService.submit(intent);
80 + print("Virtual intent submitted:\n%s", intent.toString());
81 + }
82 +}
1 +/*
2 + * Copyright 2016-present 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 +
17 +package org.onosproject.cli.net.vnet;
18 +
19 +import org.apache.karaf.shell.commands.Argument;
20 +import org.apache.karaf.shell.commands.Command;
21 +import org.apache.karaf.shell.commands.Option;
22 +import org.onosproject.cli.AbstractShellCommand;
23 +import org.onosproject.core.ApplicationId;
24 +import org.onosproject.core.CoreService;
25 +import org.onosproject.incubator.net.virtual.NetworkId;
26 +import org.onosproject.incubator.net.virtual.VirtualNetworkService;
27 +import org.onosproject.net.intent.Intent;
28 +import org.onosproject.net.intent.IntentEvent;
29 +import org.onosproject.net.intent.IntentListener;
30 +import org.onosproject.net.intent.IntentService;
31 +import org.onosproject.net.intent.IntentState;
32 +import org.onosproject.net.intent.Key;
33 +
34 +import java.math.BigInteger;
35 +import java.util.EnumSet;
36 +import java.util.Objects;
37 +import java.util.concurrent.CountDownLatch;
38 +import java.util.concurrent.TimeUnit;
39 +
40 +import static com.google.common.base.Strings.isNullOrEmpty;
41 +import static org.onosproject.net.intent.IntentState.FAILED;
42 +import static org.onosproject.net.intent.IntentState.WITHDRAWN;
43 +
44 +/**
45 + * Removes a virtual network intent.
46 + */
47 +@Command(scope = "onos", name = "remove-vnet-intent",
48 + description = "Removes the virtual network intent")
49 +public class VirtualNetworkIntentRemoveCommand extends AbstractShellCommand {
50 +
51 + @Argument(index = 0, name = "networkId", description = "Network ID",
52 + required = true, multiValued = false)
53 + Long networkId = null;
54 +
55 + @Argument(index = 1, name = "app",
56 + description = "Application ID",
57 + required = false, multiValued = false)
58 + String applicationIdString = null;
59 +
60 + @Argument(index = 2, name = "key",
61 + description = "Intent Key",
62 + required = false, multiValued = false)
63 + String keyString = null;
64 +
65 + @Option(name = "-p", aliases = "--purge",
66 + description = "Purge the intent from the store after removal",
67 + required = false, multiValued = false)
68 + private boolean purgeAfterRemove = false;
69 +
70 + @Option(name = "-s", aliases = "--sync",
71 + description = "Waits for the removal before returning",
72 + required = false, multiValued = false)
73 + private boolean sync = false;
74 +
75 + private static final EnumSet<IntentState> CAN_PURGE = EnumSet.of(WITHDRAWN, FAILED);
76 +
77 + @Override
78 + protected void execute() {
79 + VirtualNetworkService service = get(VirtualNetworkService.class);
80 + IntentService intentService = service.get(NetworkId.networkId(networkId), IntentService.class);
81 + CoreService coreService = get(CoreService.class);
82 +
83 + if (purgeAfterRemove || sync) {
84 + print("Using \"sync\" to remove/purge intents - this may take a while...");
85 + print("Check \"summary\" to see remove/purge progress.");
86 + }
87 +
88 + ApplicationId appId = appId();
89 + if (!isNullOrEmpty(applicationIdString)) {
90 + appId = coreService.getAppId(applicationIdString);
91 + if (appId == null) {
92 + print("Cannot find application Id %s", applicationIdString);
93 + return;
94 + }
95 + }
96 +
97 + if (isNullOrEmpty(keyString)) {
98 + for (Intent intent : intentService.getIntents()) {
99 + if (intent.appId().equals(appId)) {
100 + removeIntent(intentService, intent);
101 + }
102 + }
103 +
104 + } else {
105 + final Key key;
106 + if (keyString.startsWith("0x")) {
107 + // The intent uses a LongKey
108 + keyString = keyString.replaceFirst("0x", "");
109 + key = Key.of(new BigInteger(keyString, 16).longValue(), appId);
110 + } else {
111 + // The intent uses a StringKey
112 + key = Key.of(keyString, appId);
113 + }
114 +
115 + Intent intent = intentService.getIntent(key);
116 + if (intent != null) {
117 + removeIntent(intentService, intent);
118 + } else {
119 + print("Intent not found!");
120 + }
121 + }
122 + }
123 +
124 + /**
125 + * Removes the intent using the specified intentService.
126 + *
127 + * @param intentService intent service
128 + * @param intent intent
129 + */
130 + private void removeIntent(IntentService intentService, Intent intent) {
131 + IntentListener listener = null;
132 + Key key = intent.key();
133 + final CountDownLatch withdrawLatch, purgeLatch;
134 + if (purgeAfterRemove || sync) {
135 + // set up latch and listener to track uninstall progress
136 + withdrawLatch = new CountDownLatch(1);
137 + purgeLatch = purgeAfterRemove ? new CountDownLatch(1) : null;
138 + listener = (IntentEvent event) -> {
139 + if (Objects.equals(event.subject().key(), key)) {
140 + if (event.type() == IntentEvent.Type.WITHDRAWN ||
141 + event.type() == IntentEvent.Type.FAILED) {
142 + withdrawLatch.countDown();
143 + } else if (purgeAfterRemove &&
144 + event.type() == IntentEvent.Type.PURGED) {
145 + purgeLatch.countDown();
146 + }
147 + }
148 + };
149 + intentService.addListener(listener);
150 + } else {
151 + purgeLatch = null;
152 + withdrawLatch = null;
153 + }
154 +
155 + // request the withdraw
156 + intentService.withdraw(intent);
157 +
158 + if (purgeAfterRemove || sync) {
159 + try { // wait for withdraw event
160 + withdrawLatch.await(5, TimeUnit.SECONDS);
161 + } catch (InterruptedException e) {
162 + print("Timed out waiting for intent {} withdraw", key);
163 + }
164 + if (purgeAfterRemove && CAN_PURGE.contains(intentService.getIntentState(key))) {
165 + intentService.purge(intent);
166 + if (sync) { // wait for purge event
167 + /* TODO
168 + Technically, the event comes before map.remove() is called.
169 + If we depend on sync and purge working together, we will
170 + need to address this.
171 + */
172 + try {
173 + purgeLatch.await(5, TimeUnit.SECONDS);
174 + } catch (InterruptedException e) {
175 + print("Timed out waiting for intent {} purge", key);
176 + }
177 + }
178 + }
179 + }
180 +
181 + if (listener != null) {
182 + // clean up the listener
183 + intentService.removeListener(listener);
184 + }
185 + }
186 +}
...@@ -683,6 +683,12 @@ ...@@ -683,6 +683,12 @@
683 <command> 683 <command>
684 <action class="org.onosproject.cli.net.vnet.VirtualHostRemoveCommand"/> 684 <action class="org.onosproject.cli.net.vnet.VirtualHostRemoveCommand"/>
685 </command> 685 </command>
686 + <command>
687 + <action class="org.onosproject.cli.net.vnet.VirtualNetworkIntentCreateCommand"/>
688 + </command>
689 + <command>
690 + <action class="org.onosproject.cli.net.vnet.VirtualNetworkIntentRemoveCommand"/>
691 + </command>
686 </command-bundle> 692 </command-bundle>
687 693
688 <bean id="reviewAppNameCompleter" class="org.onosproject.cli.security.ReviewApplicationNameCompleter"/> 694 <bean id="reviewAppNameCompleter" class="org.onosproject.cli.security.ReviewApplicationNameCompleter"/>
......
...@@ -155,7 +155,6 @@ public class FakeIntentManager implements TestableIntentService { ...@@ -155,7 +155,6 @@ public class FakeIntentManager implements TestableIntentService {
155 155
156 @Override 156 @Override
157 public void withdraw(Intent intent) { 157 public void withdraw(Intent intent) {
158 - intents.remove(intent.key());
159 executeWithdraw(intent); 158 executeWithdraw(intent);
160 } 159 }
161 160
...@@ -167,6 +166,7 @@ public class FakeIntentManager implements TestableIntentService { ...@@ -167,6 +166,7 @@ public class FakeIntentManager implements TestableIntentService {
167 intents.remove(intent.key()); 166 intents.remove(intent.key());
168 installables.remove(intent.key()); 167 installables.remove(intent.key());
169 intentStates.remove(intent.key()); 168 intentStates.remove(intent.key());
169 + dispatch(new IntentEvent(IntentEvent.Type.PURGED, intent));
170 } 170 }
171 } 171 }
172 172
......
1 COMPILE_DEPS = [ 1 COMPILE_DEPS = [
2 '//lib:CORE_DEPS', 2 '//lib:CORE_DEPS',
3 '//incubator/api:onos-incubator-api', 3 '//incubator/api:onos-incubator-api',
4 + '//utils/rest:onlab-rest',
5 + '//incubator/net:onos-incubator-net',
6 + '//incubator/store:onos-incubator-store',
4 ] 7 ]
5 8
6 TEST_DEPS = [ 9 TEST_DEPS = [
10 + '//lib:TEST_REST',
7 '//lib:TEST_ADAPTERS', 11 '//lib:TEST_ADAPTERS',
8 '//core/common:onos-core-common', 12 '//core/common:onos-core-common',
9 '//core/store/dist:onos-core-dist', 13 '//core/store/dist:onos-core-dist',
......
...@@ -93,6 +93,14 @@ ...@@ -93,6 +93,14 @@
93 93
94 <dependency> 94 <dependency>
95 <groupId>org.onosproject</groupId> 95 <groupId>org.onosproject</groupId>
96 + <artifactId>onlab-osgi</artifactId>
97 + <version>${project.version}</version>
98 + <classifier>tests</classifier>
99 + <scope>test</scope>
100 + </dependency>
101 +
102 + <dependency>
103 + <groupId>org.onosproject</groupId>
96 <artifactId>onos-incubator-api</artifactId> 104 <artifactId>onos-incubator-api</artifactId>
97 </dependency> 105 </dependency>
98 106
...@@ -110,6 +118,17 @@ ...@@ -110,6 +118,17 @@
110 <groupId>org.apache.felix</groupId> 118 <groupId>org.apache.felix</groupId>
111 <artifactId>org.apache.felix.scr</artifactId> 119 <artifactId>org.apache.felix.scr</artifactId>
112 </dependency> 120 </dependency>
121 + <dependency>
122 + <groupId>org.onosproject</groupId>
123 + <artifactId>onos-incubator-store</artifactId>
124 + <version>${project.version}</version>
125 + <scope>test</scope>
126 + </dependency>
127 + <dependency>
128 + <groupId>org.onosproject</groupId>
129 + <artifactId>onos-incubator-net</artifactId>
130 + <version>${project.version}</version>
131 + </dependency>
113 </dependencies> 132 </dependencies>
114 133
115 </project> 134 </project>
......
1 +/*
2 + * Copyright 2016-present 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 +
17 +package org.onosproject.net.intent.impl.compiler;
18 +
19 +import org.apache.felix.scr.annotations.Activate;
20 +import org.apache.felix.scr.annotations.Component;
21 +import org.apache.felix.scr.annotations.Deactivate;
22 +import org.apache.felix.scr.annotations.Reference;
23 +import org.apache.felix.scr.annotations.ReferenceCardinality;
24 +import org.onlab.osgi.DefaultServiceDirectory;
25 +import org.onlab.osgi.ServiceDirectory;
26 +import org.onosproject.core.ApplicationId;
27 +import org.onosproject.incubator.net.tunnel.TunnelId;
28 +import org.onosproject.incubator.net.virtual.NetworkId;
29 +import org.onosproject.incubator.net.virtual.VirtualNetworkIntent;
30 +import org.onosproject.incubator.net.virtual.VirtualNetworkService;
31 +import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
32 +import org.onosproject.incubator.net.virtual.VirtualPort;
33 +import org.onosproject.net.ConnectPoint;
34 +import org.onosproject.net.EncapsulationType;
35 +import org.onosproject.net.Link;
36 +import org.onosproject.net.Path;
37 +import org.onosproject.net.intent.Constraint;
38 +import org.onosproject.net.intent.Intent;
39 +import org.onosproject.net.intent.IntentService;
40 +import org.onosproject.net.intent.Key;
41 +import org.onosproject.net.intent.PointToPointIntent;
42 +import org.onosproject.net.intent.constraint.EncapsulationConstraint;
43 +import org.onosproject.net.intent.impl.IntentCompilationException;
44 +import org.onosproject.net.topology.TopologyService;
45 +import org.slf4j.Logger;
46 +
47 +import java.util.ArrayList;
48 +import java.util.List;
49 +import java.util.Optional;
50 +import java.util.Set;
51 +
52 +import static org.slf4j.LoggerFactory.getLogger;
53 +
54 +/**
55 + * An intent compiler for {@link org.onosproject.incubator.net.virtual.VirtualNetworkIntent}.
56 + */
57 +@Component(immediate = true)
58 +public class VirtualNetworkIntentCompiler
59 + extends ConnectivityIntentCompiler<VirtualNetworkIntent> {
60 +
61 + private final Logger log = getLogger(getClass());
62 +
63 + private static final String NETWORK_ID = "networkId=";
64 + protected static final String KEY_FORMAT = "{" + NETWORK_ID + "%s, src=%s, dst=%s}";
65 +
66 + protected ServiceDirectory serviceDirectory = new DefaultServiceDirectory();
67 +
68 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
69 + protected VirtualNetworkService manager;
70 +
71 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
72 + protected IntentService intentService;
73 +
74 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
75 + protected VirtualNetworkStore store;
76 +
77 +
78 + @Activate
79 + public void activate() {
80 + intentManager.registerCompiler(VirtualNetworkIntent.class, this);
81 + }
82 +
83 + @Deactivate
84 + public void deactivate() {
85 + intentManager.unregisterCompiler(VirtualNetworkIntent.class);
86 + }
87 +
88 + @Override
89 + public List<Intent> compile(VirtualNetworkIntent intent, List<Intent> installable) {
90 +
91 + log.debug("Compiling intent: " + intent);
92 + List<Intent> intents = new ArrayList<>();
93 + Optional<Path> path = getPaths(intent).stream()
94 + .findFirst();
95 + if (path != null && path.isPresent()) {
96 + path.get().links().forEach(link -> {
97 + Intent physicalIntent = createPtPtIntent(intent, link);
98 + intents.add(physicalIntent);
99 +
100 + // store the virtual intent to physical intent tunnelId mapping
101 + store.addTunnelId(intent, TunnelId.valueOf(physicalIntent.key().toString()));
102 + });
103 + } else {
104 + throw new IntentCompilationException("Unable to find a path for intent " + intent);
105 + }
106 +
107 + return intents;
108 + }
109 +
110 + /**
111 + * Returns the paths for the virtual network intent.
112 + *
113 + * @param intent virtual network intent
114 + * @return set of paths
115 + */
116 + private Set<Path> getPaths(VirtualNetworkIntent intent) {
117 +
118 + TopologyService topologyService = manager.get(intent.networkId(), TopologyService.class);
119 + if (topologyService == null) {
120 + throw new IntentCompilationException("topologyService is null");
121 + }
122 + return topologyService.getPaths(topologyService.currentTopology(),
123 + intent.ingressPoint().deviceId(), intent.egressPoint().deviceId());
124 + }
125 +
126 + /**
127 + * Encodes the key using the network identifier, application identifer, source and destination
128 + * connect points.
129 + *
130 + * @param networkId virtual network identifier
131 + * @param applicationId application identifier
132 + * @param src source connect point
133 + * @param dst destination connect point
134 + * @return encoded key
135 + */
136 + private static Key encodeKey(NetworkId networkId, ApplicationId applicationId, ConnectPoint src, ConnectPoint dst) {
137 + String key = String.format(KEY_FORMAT, networkId, src, dst);
138 + return Key.of(key, applicationId);
139 + }
140 +
141 + /**
142 + * Creates a point-to-point intent from the virtual network intent and virtual link.
143 + *
144 + * @param intent virtual network intent
145 + * @param link virtual link
146 + * @return point to point intent
147 + */
148 + private Intent createPtPtIntent(VirtualNetworkIntent intent, Link link) {
149 + ConnectPoint ingressPoint = mapVirtualToPhysicalPort(intent.networkId(), link.src());
150 + ConnectPoint egressPoint = mapVirtualToPhysicalPort(intent.networkId(), link.dst());
151 + Key intentKey = encodeKey(intent.networkId(), intent.appId(), ingressPoint, egressPoint);
152 +
153 + List<Constraint> constraints = new ArrayList<>();
154 + constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN));
155 +
156 + // TODO Currently there can only be one intent between the ingress and egress across
157 + // all virtual networks. We may want to support multiple intents between the same src/dst pairs.
158 + PointToPointIntent physicalIntent = PointToPointIntent.builder()
159 + .key(intentKey)
160 + .appId(intent.appId())
161 + .ingressPoint(ingressPoint)
162 + .egressPoint(egressPoint)
163 + .constraints(constraints)
164 + .build();
165 + log.debug("Submitting physical intent: " + physicalIntent);
166 + intentService.submit(physicalIntent);
167 +
168 + return physicalIntent;
169 + }
170 +
171 + /**
172 + * Maps the virtual connect point to a physical connect point.
173 + *
174 + * @param networkId virtual network identifier
175 + * @param virtualCp virtual connect point
176 + * @return physical connect point
177 + */
178 + private ConnectPoint mapVirtualToPhysicalPort(NetworkId networkId, ConnectPoint virtualCp) {
179 + Set<VirtualPort> ports = manager.getVirtualPorts(networkId, virtualCp.deviceId());
180 + for (VirtualPort port : ports) {
181 + if (port.element().id().equals(virtualCp.elementId()) &&
182 + port.number().equals(virtualCp.port())) {
183 + return new ConnectPoint(port.realizedBy().element().id(), port.realizedBy().number());
184 + }
185 + }
186 + return null;
187 + }
188 +}
189 +
1 +/*
2 + * Copyright 2016-present 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 +
17 +package org.onosproject.net.intent.impl.compiler;
18 +
19 +import org.junit.After;
20 +import org.junit.Before;
21 +import org.junit.Test;
22 +import org.onlab.osgi.ServiceDirectory;
23 +import org.onlab.osgi.TestServiceDirectory;
24 +import org.onlab.rest.BaseResource;
25 +import org.onosproject.TestApplicationId;
26 +import org.onosproject.common.event.impl.TestEventDispatcher;
27 +import org.onosproject.core.ApplicationId;
28 +import org.onosproject.core.CoreService;
29 +import org.onosproject.core.CoreServiceAdapter;
30 +import org.onosproject.core.IdGenerator;
31 +import org.onosproject.incubator.net.virtual.TenantId;
32 +import org.onosproject.incubator.net.virtual.VirtualDevice;
33 +import org.onosproject.incubator.net.virtual.VirtualLink;
34 +import org.onosproject.incubator.net.virtual.VirtualNetwork;
35 +import org.onosproject.incubator.net.virtual.VirtualNetworkIntent;
36 +import org.onosproject.incubator.net.virtual.VirtualNetworkService;
37 +import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
38 +import org.onosproject.incubator.net.virtual.impl.VirtualNetworkManager;
39 +import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore;
40 +import org.onosproject.net.ConnectPoint;
41 +import org.onosproject.net.DefaultPort;
42 +import org.onosproject.net.EncapsulationType;
43 +import org.onosproject.net.Link;
44 +import org.onosproject.net.NetTestTools;
45 +import org.onosproject.net.Port;
46 +import org.onosproject.net.PortNumber;
47 +import org.onosproject.net.TestDeviceParams;
48 +import org.onosproject.net.intent.Constraint;
49 +import org.onosproject.net.intent.FakeIntentManager;
50 +import org.onosproject.net.intent.Intent;
51 +import org.onosproject.net.intent.IntentExtensionService;
52 +import org.onosproject.net.intent.IntentService;
53 +import org.onosproject.net.intent.Key;
54 +import org.onosproject.net.intent.MockIdGenerator;
55 +import org.onosproject.net.intent.TestableIntentService;
56 +import org.onosproject.net.intent.constraint.EncapsulationConstraint;
57 +import org.onosproject.store.service.TestStorageService;
58 +
59 +import java.util.ArrayList;
60 +import java.util.Collections;
61 +import java.util.List;
62 +import java.util.concurrent.atomic.AtomicLong;
63 +
64 +import static org.junit.Assert.assertEquals;
65 +import static org.onlab.junit.TestUtils.TestUtilsException;
66 +import static org.onlab.junit.TestUtils.setField;
67 +
68 +/**
69 + * Junit tests for virtual network intent compiler.
70 + */
71 +public class VirtualNetworkIntentCompilerTest extends TestDeviceParams {
72 +
73 + private CoreService coreService;
74 + private TestableIntentService intentService = new FakeIntentManager();
75 + private IntentExtensionService intentExtensionService;
76 + private final IdGenerator idGenerator = new MockIdGenerator();
77 + private VirtualNetworkIntentCompiler compiler;
78 + private VirtualNetworkManager manager;
79 + private DistributedVirtualNetworkStore virtualNetworkManagerStore;
80 + private ServiceDirectory testDirectory;
81 +
82 + private final String tenantIdValue1 = "TENANT_ID1";
83 + private static final ApplicationId APP_ID =
84 + new TestApplicationId("test");
85 +
86 + private ConnectPoint cp1;
87 + private ConnectPoint cp2;
88 + private ConnectPoint cp3;
89 + private ConnectPoint cp4;
90 + private ConnectPoint cp5;
91 + private ConnectPoint cp6;
92 + private VirtualLink link1;
93 + private VirtualLink link2;
94 + private VirtualLink link3;
95 + private VirtualLink link4;
96 + private VirtualLink link5;
97 + private VirtualLink link6;
98 +
99 + @Before
100 + public void setUp() throws TestUtilsException {
101 + virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
102 +
103 + coreService = new TestCoreService();
104 +
105 + Intent.unbindIdGenerator(idGenerator);
106 + Intent.bindIdGenerator(idGenerator);
107 +
108 + virtualNetworkManagerStore.setCoreService(coreService);
109 + setField(coreService, "coreService", new TestCoreService());
110 + setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
111 + virtualNetworkManagerStore.activate();
112 +
113 + manager = new VirtualNetworkManager();
114 + manager.setStore(virtualNetworkManagerStore);
115 + manager.setIntentService(intentService);
116 + NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
117 + manager.activate();
118 +
119 + // Register a compiler and an installer both setup for success.
120 + intentExtensionService = intentService;
121 +
122 + testDirectory = new TestServiceDirectory()
123 + .add(VirtualNetworkService.class, manager)
124 + .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
125 + .add(IntentService.class, intentService);
126 + BaseResource.setServiceDirectory(testDirectory);
127 +
128 + compiler = new VirtualNetworkIntentCompiler();
129 + compiler.manager = manager;
130 + compiler.intentService = intentService;
131 + compiler.store = virtualNetworkManagerStore;
132 + compiler.intentManager = intentExtensionService;
133 + compiler.serviceDirectory = testDirectory;
134 + }
135 +
136 + @After
137 + public void tearDown() {
138 + Intent.unbindIdGenerator(idGenerator);
139 + manager.deactivate();
140 + }
141 +
142 + /**
143 + * Method to create the virtual network for further testing.
144 + *
145 + * @return virtual network
146 + */
147 + private VirtualNetwork setupVirtualNetworkTopology() {
148 + manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
149 + VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
150 + VirtualDevice virtualDevice1 =
151 + manager.createVirtualDevice(virtualNetwork.id(), DID1);
152 + VirtualDevice virtualDevice2 =
153 + manager.createVirtualDevice(virtualNetwork.id(), DID2);
154 + VirtualDevice virtualDevice3 =
155 + manager.createVirtualDevice(virtualNetwork.id(), DID3);
156 + VirtualDevice virtualDevice4 =
157 + manager.createVirtualDevice(virtualNetwork.id(), DID4);
158 +
159 + Port port1 = new DefaultPort(virtualDevice1, PortNumber.portNumber(1), true);
160 + manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(), port1.number(), port1);
161 + cp1 = new ConnectPoint(virtualDevice1.id(), port1.number());
162 +
163 + Port port2 = new DefaultPort(virtualDevice1, PortNumber.portNumber(2), true);
164 + manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(), port2.number(), port2);
165 + cp2 = new ConnectPoint(virtualDevice1.id(), port2.number());
166 +
167 + Port port3 = new DefaultPort(virtualDevice2, PortNumber.portNumber(3), true);
168 + manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(), port3.number(), port3);
169 + cp3 = new ConnectPoint(virtualDevice2.id(), port3.number());
170 +
171 + Port port4 = new DefaultPort(virtualDevice2, PortNumber.portNumber(4), true);
172 + manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(), port4.number(), port4);
173 + cp4 = new ConnectPoint(virtualDevice2.id(), port4.number());
174 +
175 + Port port5 = new DefaultPort(virtualDevice3, PortNumber.portNumber(5), true);
176 + manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(), port5.number(), port5);
177 + cp5 = new ConnectPoint(virtualDevice3.id(), port5.number());
178 +
179 + Port port6 = new DefaultPort(virtualDevice3, PortNumber.portNumber(6), true);
180 + manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(), port6.number(), port6);
181 + cp6 = new ConnectPoint(virtualDevice3.id(), port6.number());
182 +
183 + link1 = manager.createVirtualLink(virtualNetwork.id(), cp1, cp3);
184 + virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
185 + link2 = manager.createVirtualLink(virtualNetwork.id(), cp3, cp1);
186 + virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
187 + link3 = manager.createVirtualLink(virtualNetwork.id(), cp4, cp5);
188 + virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE);
189 + link4 = manager.createVirtualLink(virtualNetwork.id(), cp5, cp4);
190 + virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE);
191 +
192 + return virtualNetwork;
193 + }
194 +
195 + @Test
196 + public void testCompiler() {
197 + compiler.activate();
198 + VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
199 +
200 + Key intentKey = Key.of("test", APP_ID);
201 +
202 + List<Constraint> constraints = new ArrayList<>();
203 + constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN));
204 +
205 + VirtualNetworkIntent virtualIntent = VirtualNetworkIntent.builder()
206 + .networkId(virtualNetwork.id())
207 + .key(intentKey)
208 + .appId(APP_ID)
209 + .ingressPoint(cp1)
210 + .egressPoint(cp5)
211 + .constraints(constraints)
212 + .build();
213 +
214 + List<Intent> compiled = compiler.compile(virtualIntent, Collections.emptyList());
215 + assertEquals("The virtual intents size is not as expected.", 2, compiled.size());
216 +
217 + compiler.deactivate();
218 + }
219 +
220 +
221 + /**
222 + * Core service test class.
223 + */
224 + private class TestCoreService extends CoreServiceAdapter {
225 +
226 + @Override
227 + public IdGenerator getIdGenerator(String topic) {
228 + return new IdGenerator() {
229 + private AtomicLong counter = new AtomicLong(0);
230 +
231 + @Override
232 + public long getNewId() {
233 + return counter.getAndIncrement();
234 + }
235 + };
236 + }
237 + }
238 +
239 +}
...@@ -9,6 +9,7 @@ COMPILE_DEPS = [ ...@@ -9,6 +9,7 @@ COMPILE_DEPS = [
9 '//lib:netty-handler', 9 '//lib:netty-handler',
10 '//lib:netty-transport-native-epoll', 10 '//lib:netty-transport-native-epoll',
11 '//lib:commons-math3', 11 '//lib:commons-math3',
12 + '//incubator/api:onos-incubator-api',
12 ] 13 ]
13 14
14 TEST_DEPS = [ 15 TEST_DEPS = [
......
...@@ -27,6 +27,8 @@ import org.onlab.util.KryoNamespace; ...@@ -27,6 +27,8 @@ import org.onlab.util.KryoNamespace;
27 import org.onosproject.cluster.ClusterService; 27 import org.onosproject.cluster.ClusterService;
28 import org.onosproject.cluster.ControllerNode; 28 import org.onosproject.cluster.ControllerNode;
29 import org.onosproject.cluster.NodeId; 29 import org.onosproject.cluster.NodeId;
30 +import org.onosproject.incubator.net.virtual.NetworkId;
31 +import org.onosproject.incubator.net.virtual.VirtualNetworkIntent;
30 import org.onosproject.net.intent.Intent; 32 import org.onosproject.net.intent.Intent;
31 import org.onosproject.net.intent.IntentData; 33 import org.onosproject.net.intent.IntentData;
32 import org.onosproject.net.intent.IntentEvent; 34 import org.onosproject.net.intent.IntentEvent;
...@@ -97,6 +99,8 @@ public class GossipIntentStore ...@@ -97,6 +99,8 @@ public class GossipIntentStore
97 KryoNamespace.Builder intentSerializer = KryoNamespace.newBuilder() 99 KryoNamespace.Builder intentSerializer = KryoNamespace.newBuilder()
98 .register(KryoNamespaces.API) 100 .register(KryoNamespaces.API)
99 .register(IntentData.class) 101 .register(IntentData.class)
102 + .register(VirtualNetworkIntent.class)
103 + .register(NetworkId.class)
100 .register(MultiValuedTimestamp.class); 104 .register(MultiValuedTimestamp.class);
101 105
102 currentMap = storageService.<Key, IntentData>eventuallyConsistentMapBuilder() 106 currentMap = storageService.<Key, IntentData>eventuallyConsistentMapBuilder()
......
1 +/*
2 + * Copyright 2016-present 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 +
17 +package org.onosproject.incubator.net.virtual;
18 +
19 +import com.google.common.annotations.Beta;
20 +import com.google.common.base.MoreObjects;
21 +import org.onosproject.core.ApplicationId;
22 +import org.onosproject.net.ConnectPoint;
23 +import org.onosproject.net.flow.TrafficSelector;
24 +import org.onosproject.net.flow.TrafficTreatment;
25 +import org.onosproject.net.intent.ConnectivityIntent;
26 +import org.onosproject.net.intent.Constraint;
27 +import org.onosproject.net.intent.Key;
28 +
29 +import java.util.Collections;
30 +import java.util.List;
31 +
32 +import static com.google.common.base.Preconditions.checkArgument;
33 +import static com.google.common.base.Preconditions.checkNotNull;
34 +
35 +/**
36 + * Abstraction of VirtualNetworkIntent connectivity.
37 + */
38 +@Beta
39 +public final class VirtualNetworkIntent extends ConnectivityIntent {
40 +
41 + private final NetworkId networkId;
42 + private final ConnectPoint ingressPoint;
43 + private final ConnectPoint egressPoint;
44 +
45 + private static final String NETWORK_ID_NULL = "Network ID cannot be null";
46 +
47 + /**
48 + * Returns a new point to point intent builder. The application id,
49 + * ingress point and egress point are required fields. If they are
50 + * not set by calls to the appropriate methods, an exception will
51 + * be thrown.
52 + *
53 + * @return point to point builder
54 + */
55 + public static VirtualNetworkIntent.Builder builder() {
56 + return new VirtualNetworkIntent.Builder();
57 + }
58 +
59 + /**
60 + * Builder of a point to point intent.
61 + */
62 + public static final class Builder extends ConnectivityIntent.Builder {
63 + NetworkId networkId;
64 + ConnectPoint ingressPoint;
65 + ConnectPoint egressPoint;
66 +
67 + /**
68 + * Builder constructor.
69 + */
70 + private Builder() {
71 + // Hide constructor
72 + }
73 +
74 + @Override
75 + public VirtualNetworkIntent.Builder appId(ApplicationId appId) {
76 + return (VirtualNetworkIntent.Builder) super.appId(appId);
77 + }
78 +
79 + @Override
80 + public VirtualNetworkIntent.Builder key(Key key) {
81 + return (VirtualNetworkIntent.Builder) super.key(key);
82 + }
83 +
84 + @Override
85 + public VirtualNetworkIntent.Builder selector(TrafficSelector selector) {
86 + return (VirtualNetworkIntent.Builder) super.selector(selector);
87 + }
88 +
89 + @Override
90 + public VirtualNetworkIntent.Builder treatment(TrafficTreatment treatment) {
91 + return (VirtualNetworkIntent.Builder) super.treatment(treatment);
92 + }
93 +
94 + @Override
95 + public VirtualNetworkIntent.Builder constraints(List<Constraint> constraints) {
96 + return (VirtualNetworkIntent.Builder) super.constraints(constraints);
97 + }
98 +
99 + @Override
100 + public VirtualNetworkIntent.Builder priority(int priority) {
101 + return (VirtualNetworkIntent.Builder) super.priority(priority);
102 + }
103 +
104 + /**
105 + * Sets the virtual network of the virtual network intent.
106 + *
107 + * @param networkId virtual network identifier
108 + * @return this builder
109 + */
110 + public VirtualNetworkIntent.Builder networkId(NetworkId networkId) {
111 + this.networkId = networkId;
112 + return this;
113 + }
114 +
115 + /**
116 + * Sets the ingress point of the virtual network intent that will be built.
117 + *
118 + * @param ingressPoint ingress connect point
119 + * @return this builder
120 + */
121 + public VirtualNetworkIntent.Builder ingressPoint(ConnectPoint ingressPoint) {
122 + this.ingressPoint = ingressPoint;
123 + return this;
124 + }
125 +
126 + /**
127 + * Sets the egress point of the virtual network intent that will be built.
128 + *
129 + * @param egressPoint egress connect point
130 + * @return this builder
131 + */
132 + public VirtualNetworkIntent.Builder egressPoint(ConnectPoint egressPoint) {
133 + this.egressPoint = egressPoint;
134 + return this;
135 + }
136 +
137 + /**
138 + * Builds a virtual network intent from the accumulated parameters.
139 + *
140 + * @return virtual network intent
141 + */
142 + public VirtualNetworkIntent build() {
143 +
144 + return new VirtualNetworkIntent(
145 + networkId,
146 + appId,
147 + key,
148 + selector,
149 + treatment,
150 + ingressPoint,
151 + egressPoint,
152 + constraints,
153 + priority
154 + );
155 + }
156 + }
157 +
158 +
159 + /**
160 + * Creates a new point-to-point intent with the supplied ingress/egress
161 + * ports and constraints.
162 + *
163 + * @param networkId virtual network identifier
164 + * @param appId application identifier
165 + * @param key key of the intent
166 + * @param selector traffic selector
167 + * @param treatment treatment
168 + * @param ingressPoint ingress port
169 + * @param egressPoint egress port
170 + * @param constraints optional list of constraints
171 + * @param priority priority to use for flows generated by this intent
172 + * @throws NullPointerException if {@code ingressPoint} or
173 + * {@code egressPoints} or {@code appId} is null.
174 + */
175 + private VirtualNetworkIntent(NetworkId networkId,
176 + ApplicationId appId,
177 + Key key,
178 + TrafficSelector selector,
179 + TrafficTreatment treatment,
180 + ConnectPoint ingressPoint,
181 + ConnectPoint egressPoint,
182 + List<Constraint> constraints,
183 + int priority) {
184 + super(appId, key, Collections.emptyList(), selector, treatment, constraints,
185 + priority);
186 +
187 + checkNotNull(networkId, NETWORK_ID_NULL);
188 + checkArgument(!ingressPoint.equals(egressPoint),
189 + "ingress and egress should be different (ingress: %s, egress: %s)", ingressPoint, egressPoint);
190 +
191 + this.networkId = networkId;
192 + this.ingressPoint = checkNotNull(ingressPoint);
193 + this.egressPoint = checkNotNull(egressPoint);
194 + }
195 +
196 + /**
197 + * Constructor for serializer.
198 + */
199 + protected VirtualNetworkIntent() {
200 + super();
201 + this.networkId = null;
202 + this.ingressPoint = null;
203 + this.egressPoint = null;
204 + }
205 +
206 + /**
207 + * Returns the virtual network identifier.
208 + *
209 + * @return network identifier
210 + */
211 + public NetworkId networkId() {
212 + return networkId;
213 + }
214 +
215 + /**
216 + * Returns the port on which the ingress traffic should be connected to
217 + * the egress.
218 + *
219 + * @return ingress port
220 + */
221 + public ConnectPoint ingressPoint() {
222 + return ingressPoint;
223 + }
224 +
225 + /**
226 + * Returns the port on which the traffic should egress.
227 + *
228 + * @return egress port
229 + */
230 + public ConnectPoint egressPoint() {
231 + return egressPoint;
232 + }
233 +
234 + @Override
235 + public String toString() {
236 + return MoreObjects.toStringHelper(getClass())
237 + .add("networkId", networkId)
238 + .add("id", id())
239 + .add("key", key())
240 + .add("appId", appId())
241 + .add("priority", priority())
242 + .add("resources", resources())
243 + .add("selector", selector())
244 + .add("treatment", treatment())
245 + .add("ingress", ingressPoint)
246 + .add("egress", egressPoint)
247 + .add("constraints", constraints())
248 + .toString();
249 + }
250 +
251 +}
...@@ -26,6 +26,10 @@ import org.onosproject.net.HostLocation; ...@@ -26,6 +26,10 @@ import org.onosproject.net.HostLocation;
26 import org.onosproject.net.Link; 26 import org.onosproject.net.Link;
27 import org.onosproject.net.Port; 27 import org.onosproject.net.Port;
28 import org.onosproject.net.PortNumber; 28 import org.onosproject.net.PortNumber;
29 +import org.onosproject.net.intent.Intent;
30 +import org.onosproject.net.intent.IntentData;
31 +import org.onosproject.net.intent.IntentState;
32 +import org.onosproject.net.intent.Key;
29 import org.onosproject.store.Store; 33 import org.onosproject.store.Store;
30 34
31 import java.util.Set; 35 import java.util.Set;
...@@ -223,4 +227,73 @@ public interface VirtualNetworkStore ...@@ -223,4 +227,73 @@ public interface VirtualNetworkStore
223 */ 227 */
224 Set<VirtualPort> getPorts(NetworkId networkId, DeviceId deviceId); 228 Set<VirtualPort> getPorts(NetworkId networkId, DeviceId deviceId);
225 229
230 + /**
231 + * Add or update the intent to the store.
232 + *
233 + * @param intent virtual intent
234 + * @param state intent state
235 + */
236 + void addOrUpdateIntent(Intent intent, IntentState state);
237 +
238 + /**
239 + * Remove the virtual intent from the store.
240 + *
241 + * @param intentKey intent key
242 + * @return intent data
243 + */
244 + IntentData removeIntent(Key intentKey);
245 +
246 + /**
247 + * Adds the intent to tunnel identifier mapping to the store.
248 + *
249 + * @param intent intent
250 + * @param tunnelId tunnel identifier
251 + */
252 + void addTunnelId(Intent intent, TunnelId tunnelId);
253 +
254 + /**
255 + * Return the set of tunnel identifiers store against the intent.
256 + *
257 + * @param intent intent
258 + * @return set of tunnel identifiers
259 + */
260 + Set<TunnelId> getTunnelIds(Intent intent);
261 +
262 + /**
263 + * Removes the intent to tunnel identifier mapping from the store.
264 + *
265 + * @param intent intent
266 + * @param tunnelId tunnel identifier
267 + */
268 + void removeTunnelId(Intent intent, TunnelId tunnelId);
269 +
270 + /**
271 + * Return all intents.
272 + *
273 + * @return set of intents
274 + */
275 + Set<Intent> getIntents();
276 +
277 + /**
278 + * Return the intent for the specified intent key.
279 + *
280 + * @param key intent key
281 + * @return intent
282 + */
283 + Intent getIntent(Key key);
284 +
285 + /**
286 + * Return the set of intent data.
287 + *
288 + * @return set of intent data
289 + */
290 + Set<IntentData> getIntentData();
291 +
292 + /**
293 + * Return the intent data matching the intent key.
294 + *
295 + * @param key intent key
296 + * @return intent data
297 + */
298 + IntentData getIntentData(Key key);
226 } 299 }
......
...@@ -2,13 +2,15 @@ COMPILE_DEPS = [ ...@@ -2,13 +2,15 @@ COMPILE_DEPS = [
2 '//lib:CORE_DEPS', 2 '//lib:CORE_DEPS',
3 '//core/common:onos-core-common', 3 '//core/common:onos-core-common',
4 '//incubator/api:onos-incubator-api', 4 '//incubator/api:onos-incubator-api',
5 + '//incubator/store:onos-incubator-store',
6 + '//utils/rest:onlab-rest',
5 ] 7 ]
6 8
7 TEST_DEPS = [ 9 TEST_DEPS = [
10 + '//lib:TEST_REST',
8 '//lib:TEST_ADAPTERS', 11 '//lib:TEST_ADAPTERS',
9 '//core/api:onos-api-tests', 12 '//core/api:onos-api-tests',
10 '//core/common:onos-core-common-tests', 13 '//core/common:onos-core-common-tests',
11 - '//incubator/store:onos-incubator-store',
12 '//core/store/serializers:onos-core-serializers', 14 '//core/store/serializers:onos-core-serializers',
13 '//lib:concurrent-trees', 15 '//lib:concurrent-trees',
14 ] 16 ]
......
...@@ -95,6 +95,14 @@ ...@@ -95,6 +95,14 @@
95 <groupId>org.apache.felix</groupId> 95 <groupId>org.apache.felix</groupId>
96 <artifactId>org.apache.felix.scr.annotations</artifactId> 96 <artifactId>org.apache.felix.scr.annotations</artifactId>
97 </dependency> 97 </dependency>
98 +
99 + <dependency>
100 + <groupId>org.onosproject</groupId>
101 + <artifactId>onlab-osgi</artifactId>
102 + <version>${project.version}</version>
103 + <classifier>tests</classifier>
104 + <scope>test</scope>
105 + </dependency>
98 </dependencies> 106 </dependencies>
99 107
100 <build> 108 <build>
......
1 +/*
2 + * Copyright 2016-present 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 +
17 +package org.onosproject.incubator.net.virtual.impl;
18 +
19 +import com.google.common.collect.Iterators;
20 +import org.onlab.osgi.ServiceDirectory;
21 +import org.onosproject.event.AbstractListenerManager;
22 +import org.onosproject.incubator.net.virtual.VirtualNetwork;
23 +import org.onosproject.incubator.net.virtual.VirtualNetworkIntent;
24 +import org.onosproject.incubator.net.virtual.VirtualNetworkService;
25 +import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
26 +import org.onosproject.incubator.net.virtual.VirtualPort;
27 +import org.onosproject.net.ConnectPoint;
28 +import org.onosproject.net.DeviceId;
29 +import org.onosproject.net.Port;
30 +import org.onosproject.net.PortNumber;
31 +import org.onosproject.net.intent.Intent;
32 +import org.onosproject.net.intent.IntentData;
33 +import org.onosproject.net.intent.IntentEvent;
34 +import org.onosproject.net.intent.IntentListener;
35 +import org.onosproject.net.intent.IntentPartitionService;
36 +import org.onosproject.net.intent.IntentService;
37 +import org.onosproject.net.intent.IntentState;
38 +import org.onosproject.net.intent.Key;
39 +import org.slf4j.Logger;
40 +import org.slf4j.LoggerFactory;
41 +
42 +import java.util.ArrayList;
43 +import java.util.List;
44 +import java.util.Optional;
45 +
46 +import static com.google.common.base.Preconditions.*;
47 +
48 +/**
49 + * intent service implementation built on the virtual network service.
50 + */
51 +public class VirtualNetworkIntentService extends AbstractListenerManager<IntentEvent, IntentListener>
52 + implements IntentService, VnetService {
53 +
54 + private final Logger log = LoggerFactory.getLogger(getClass());
55 +
56 + private static final String NETWORK_NULL = "Network cannot be null";
57 + private static final String NETWORK_ID_NULL = "Network ID cannot be null";
58 + private static final String DEVICE_NULL = "Device cannot be null";
59 + private static final String INTENT_NULL = "Intent cannot be null";
60 + private static final String KEY_NULL = "Key cannot be null";
61 + private static final String APP_ID_NULL = "Intent app identifier cannot be null";
62 + private static final String INTENT_KEY_NULL = "Intent key cannot be null";
63 + private static final String CP_NULL = "Connect Point cannot be null";
64 +
65 + protected IntentService intentService;
66 + protected VirtualNetworkStore store;
67 + protected IntentPartitionService partitionService;
68 +
69 + private final VirtualNetwork network;
70 + private final VirtualNetworkService manager;
71 +
72 + /**
73 + * Creates a new VirtualNetworkIntentService object.
74 + *
75 + * @param virtualNetworkManager virtual network manager service
76 + * @param network virtual network
77 + * @param serviceDirectory service directory
78 + */
79 + public VirtualNetworkIntentService(VirtualNetworkService virtualNetworkManager, VirtualNetwork network,
80 + ServiceDirectory serviceDirectory) {
81 + checkNotNull(network, NETWORK_NULL);
82 + this.network = network;
83 + this.manager = virtualNetworkManager;
84 + this.store = serviceDirectory.get(VirtualNetworkStore.class);
85 + this.intentService = serviceDirectory.get(IntentService.class);
86 + this.partitionService = serviceDirectory.get(IntentPartitionService.class);
87 + }
88 +
89 + @Override
90 + public void submit(Intent intent) {
91 + checkNotNull(intent, INTENT_NULL);
92 + checkState(intent instanceof VirtualNetworkIntent, "Only VirtualNetworkIntent is supported.");
93 + checkArgument(validateIntent((VirtualNetworkIntent) intent), "Invalid Intent");
94 +
95 + intentService.submit(intent);
96 + }
97 +
98 + /**
99 + * Returns true if the virtual network intent is valid.
100 + *
101 + * @param intent virtual network intent
102 + * @return true if intent is valid
103 + */
104 + private boolean validateIntent(VirtualNetworkIntent intent) {
105 + checkNotNull(intent, INTENT_NULL);
106 + checkNotNull(intent.networkId(), NETWORK_ID_NULL);
107 + checkNotNull(intent.appId(), APP_ID_NULL);
108 + checkNotNull(intent.key(), INTENT_KEY_NULL);
109 + ConnectPoint ingressPoint = intent.ingressPoint();
110 + ConnectPoint egressPoint = intent.egressPoint();
111 +
112 + return (validateConnectPoint(ingressPoint) && validateConnectPoint(egressPoint));
113 + }
114 +
115 + /**
116 + * Returns true if the connect point is valid.
117 + *
118 + * @param connectPoint connect point
119 + * @return true if connect point is valid
120 + */
121 + private boolean validateConnectPoint(ConnectPoint connectPoint) {
122 + checkNotNull(connectPoint, CP_NULL);
123 + Port port = getPort(connectPoint.deviceId(), connectPoint.port());
124 + return port == null ? false : true;
125 + }
126 +
127 + /**
128 + * Returns the virtual port for the given device identifier and port number.
129 + *
130 + * @param deviceId virtual device identifier
131 + * @param portNumber virtual port number
132 + * @return virtual port
133 + */
134 + private Port getPort(DeviceId deviceId, PortNumber portNumber) {
135 + checkNotNull(deviceId, DEVICE_NULL);
136 +
137 + Optional<VirtualPort> foundPort = manager.getVirtualPorts(this.network.id(), deviceId)
138 + .stream()
139 + .filter(port -> port.number().equals(portNumber))
140 + .findFirst();
141 + if (foundPort.isPresent()) {
142 + return foundPort.get();
143 + }
144 + return null;
145 + }
146 +
147 + @Override
148 + public void withdraw(Intent intent) {
149 + checkNotNull(intent, INTENT_NULL);
150 + // Withdraws the physical intents created due to the virtual intents.
151 + store.getTunnelIds(intent)
152 + .forEach(tunnelId -> {
153 + Key intentKey = Key.of(tunnelId.id(), intent.appId());
154 + Intent physicalIntent = intentService.getIntent(intentKey);
155 + checkNotNull(physicalIntent, INTENT_NULL);
156 +
157 + // Withdraw the physical intent(s)
158 + log.info("Withdrawing pt-pt intent: " + physicalIntent);
159 + intentService.withdraw(physicalIntent);
160 + });
161 + // Now withdraw the virtual intent
162 + log.info("Withdrawing virtual intent: " + intent);
163 + intentService.withdraw(intent);
164 + }
165 +
166 + @Override
167 + public void purge(Intent intent) {
168 + checkNotNull(intent, INTENT_NULL);
169 + // Purges the physical intents created for each tunnelId.
170 + store.getTunnelIds(intent)
171 + .forEach(tunnelId -> {
172 + Key intentKey = Key.of(tunnelId.id(), intent.appId());
173 + Intent physicalIntent = intentService.getIntent(intentKey);
174 + checkNotNull(physicalIntent, INTENT_NULL);
175 +
176 + // Purge the physical intent(s)
177 + intentService.purge(physicalIntent);
178 + store.removeTunnelId(intent, tunnelId);
179 + });
180 + // Now purge the virtual intent
181 + intentService.purge(intent);
182 + }
183 +
184 + @Override
185 + public Intent getIntent(Key key) {
186 + checkNotNull(key, KEY_NULL);
187 + return store.getIntent(key);
188 + }
189 +
190 + @Override
191 + public Iterable<Intent> getIntents() {
192 + return store.getIntents();
193 + }
194 +
195 + @Override
196 + public Iterable<IntentData> getIntentData() {
197 + return store.getIntentData();
198 + }
199 +
200 + @Override
201 + public long getIntentCount() {
202 + return Iterators.size(getIntents().iterator());
203 + }
204 +
205 + @Override
206 + public IntentState getIntentState(Key intentKey) {
207 + checkNotNull(intentKey, KEY_NULL);
208 + return store.getIntentData(intentKey).state();
209 + }
210 +
211 + @Override
212 + public List<Intent> getInstallableIntents(Key intentKey) {
213 + List<Intent> intents = new ArrayList<>();
214 + getIntentData().forEach(intentData -> {
215 + if (intentData.intent().key().equals(intentKey)) {
216 + intents.addAll(intentData.installables());
217 + }
218 + });
219 + return intents;
220 + }
221 +
222 + @Override
223 + public boolean isLocal(Key intentKey) {
224 + checkNotNull(intentKey, INTENT_KEY_NULL);
225 + Intent intent = getIntent(intentKey);
226 + checkNotNull(intent, INTENT_NULL);
227 + return partitionService.isMine(intentKey);
228 + }
229 +
230 + @Override
231 + public Iterable<Intent> getPending() {
232 + return null;
233 + }
234 +
235 +
236 + @Override
237 + public VirtualNetwork network() {
238 + return network;
239 + }
240 +}
...@@ -22,6 +22,7 @@ import org.apache.felix.scr.annotations.Deactivate; ...@@ -22,6 +22,7 @@ import org.apache.felix.scr.annotations.Deactivate;
22 import org.apache.felix.scr.annotations.Reference; 22 import org.apache.felix.scr.annotations.Reference;
23 import org.apache.felix.scr.annotations.ReferenceCardinality; 23 import org.apache.felix.scr.annotations.ReferenceCardinality;
24 import org.apache.felix.scr.annotations.Service; 24 import org.apache.felix.scr.annotations.Service;
25 +import org.onlab.osgi.DefaultServiceDirectory;
25 import org.onlab.packet.IpAddress; 26 import org.onlab.packet.IpAddress;
26 import org.onlab.packet.MacAddress; 27 import org.onlab.packet.MacAddress;
27 import org.onlab.packet.VlanId; 28 import org.onlab.packet.VlanId;
...@@ -34,9 +35,9 @@ import org.onosproject.incubator.net.virtual.VirtualLink; ...@@ -34,9 +35,9 @@ import org.onosproject.incubator.net.virtual.VirtualLink;
34 import org.onosproject.incubator.net.virtual.VirtualNetwork; 35 import org.onosproject.incubator.net.virtual.VirtualNetwork;
35 import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService; 36 import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
36 import org.onosproject.incubator.net.virtual.VirtualNetworkEvent; 37 import org.onosproject.incubator.net.virtual.VirtualNetworkEvent;
38 +import org.onosproject.incubator.net.virtual.VirtualNetworkIntent;
37 import org.onosproject.incubator.net.virtual.VirtualNetworkListener; 39 import org.onosproject.incubator.net.virtual.VirtualNetworkListener;
38 import org.onosproject.incubator.net.virtual.VirtualNetworkProvider; 40 import org.onosproject.incubator.net.virtual.VirtualNetworkProvider;
39 -import org.onosproject.incubator.net.virtual.VirtualNetworkProviderRegistry;
40 import org.onosproject.incubator.net.virtual.VirtualNetworkProviderService; 41 import org.onosproject.incubator.net.virtual.VirtualNetworkProviderService;
41 import org.onosproject.incubator.net.virtual.VirtualNetworkService; 42 import org.onosproject.incubator.net.virtual.VirtualNetworkService;
42 import org.onosproject.incubator.net.virtual.VirtualNetworkStore; 43 import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
...@@ -50,6 +51,10 @@ import org.onosproject.net.Link; ...@@ -50,6 +51,10 @@ import org.onosproject.net.Link;
50 import org.onosproject.net.Port; 51 import org.onosproject.net.Port;
51 import org.onosproject.net.PortNumber; 52 import org.onosproject.net.PortNumber;
52 import org.onosproject.net.device.DeviceService; 53 import org.onosproject.net.device.DeviceService;
54 +import org.onosproject.net.intent.IntentEvent;
55 +import org.onosproject.net.intent.IntentListener;
56 +import org.onosproject.net.intent.IntentService;
57 +import org.onosproject.net.intent.IntentState;
53 import org.onosproject.net.link.LinkService; 58 import org.onosproject.net.link.LinkService;
54 import org.onosproject.net.provider.AbstractListenerProviderRegistry; 59 import org.onosproject.net.provider.AbstractListenerProviderRegistry;
55 import org.onosproject.net.provider.AbstractProviderService; 60 import org.onosproject.net.provider.AbstractProviderService;
...@@ -70,7 +75,7 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -70,7 +75,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
70 public class VirtualNetworkManager 75 public class VirtualNetworkManager
71 extends AbstractListenerProviderRegistry<VirtualNetworkEvent, VirtualNetworkListener, 76 extends AbstractListenerProviderRegistry<VirtualNetworkEvent, VirtualNetworkListener,
72 VirtualNetworkProvider, VirtualNetworkProviderService> 77 VirtualNetworkProvider, VirtualNetworkProviderService>
73 - implements VirtualNetworkService, VirtualNetworkAdminService, VirtualNetworkProviderRegistry { 78 + implements VirtualNetworkService, VirtualNetworkAdminService {
74 79
75 private final Logger log = LoggerFactory.getLogger(getClass()); 80 private final Logger log = LoggerFactory.getLogger(getClass());
76 81
...@@ -78,28 +83,51 @@ public class VirtualNetworkManager ...@@ -78,28 +83,51 @@ public class VirtualNetworkManager
78 private static final String NETWORK_NULL = "Network ID cannot be null"; 83 private static final String NETWORK_NULL = "Network ID cannot be null";
79 private static final String DEVICE_NULL = "Device ID cannot be null"; 84 private static final String DEVICE_NULL = "Device ID cannot be null";
80 private static final String LINK_POINT_NULL = "Link end-point cannot be null"; 85 private static final String LINK_POINT_NULL = "Link end-point cannot be null";
81 - private static final String VIRTUAL_LINK_NULL = "Virtual Link cannot be null";
82 86
83 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 87 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
84 protected VirtualNetworkStore store; 88 protected VirtualNetworkStore store;
85 89
90 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
91 + protected IntentService intentService;
92 +
93 + private final InternalVirtualIntentListener intentListener = new InternalVirtualIntentListener();
94 +
86 private VirtualNetworkStoreDelegate delegate = this::post; 95 private VirtualNetworkStoreDelegate delegate = this::post;
87 96
88 // TODO: figure out how to coordinate "implementation" of a virtual network in a cluster 97 // TODO: figure out how to coordinate "implementation" of a virtual network in a cluster
89 98
99 + /**
100 + * Only used for Junit test methods outside of this package.
101 + *
102 + * @param store virtual network store
103 + */
104 + public void setStore(VirtualNetworkStore store) {
105 + this.store = store;
106 + }
107 +
108 + /**
109 + * Only used for Junit test methods outside of this package.
110 + *
111 + * @param intentService intent service
112 + */
113 +
114 + public void setIntentService(IntentService intentService) {
115 + this.intentService = intentService;
116 + }
117 +
90 @Activate 118 @Activate
91 - protected void activate() { 119 + public void activate() {
92 store.setDelegate(delegate); 120 store.setDelegate(delegate);
93 eventDispatcher.addSink(VirtualNetworkEvent.class, listenerRegistry); 121 eventDispatcher.addSink(VirtualNetworkEvent.class, listenerRegistry);
94 - 122 + intentService.addListener(intentListener);
95 log.info("Started"); 123 log.info("Started");
96 } 124 }
97 125
98 @Deactivate 126 @Deactivate
99 - protected void deactivate() { 127 + public void deactivate() {
100 store.unsetDelegate(delegate); 128 store.unsetDelegate(delegate);
101 eventDispatcher.removeSink(VirtualNetworkEvent.class); 129 eventDispatcher.removeSink(VirtualNetworkEvent.class);
102 - 130 + intentService.removeListener(intentListener);
103 log.info("Stopped"); 131 log.info("Stopped");
104 } 132 }
105 133
...@@ -167,48 +195,18 @@ public class VirtualNetworkManager ...@@ -167,48 +195,18 @@ public class VirtualNetworkManager
167 checkNotNull(networkId, NETWORK_NULL); 195 checkNotNull(networkId, NETWORK_NULL);
168 checkNotNull(src, LINK_POINT_NULL); 196 checkNotNull(src, LINK_POINT_NULL);
169 checkNotNull(dst, LINK_POINT_NULL); 197 checkNotNull(dst, LINK_POINT_NULL);
170 - VirtualLink virtualLink = store.addLink(networkId, src, dst, Link.State.INACTIVE, null); 198 + return store.addLink(networkId, src, dst, Link.State.ACTIVE, null);
171 - checkNotNull(virtualLink, VIRTUAL_LINK_NULL);
172 -
173 - if (virtualLink.providerId() != null) {
174 - VirtualNetworkProvider provider = getProvider(virtualLink.providerId());
175 - if (provider != null) {
176 - TunnelId tunnelId = provider.createTunnel(networkId, mapVirtualToPhysicalPort(networkId, src),
177 - mapVirtualToPhysicalPort(networkId, dst));
178 - store.updateLink(virtualLink, tunnelId, Link.State.INACTIVE);
179 - }
180 - }
181 - return virtualLink;
182 - }
183 -
184 - /**
185 - * Maps the virtual connect point to a physical connect point.
186 - *
187 - * @param networkId network identifier
188 - * @param virtualCp virtual connect point
189 - * @return physical connect point
190 - */
191 - private ConnectPoint mapVirtualToPhysicalPort(NetworkId networkId,
192 - ConnectPoint virtualCp) {
193 - Set<VirtualPort> ports = store.getPorts(networkId, virtualCp.deviceId());
194 - for (VirtualPort port : ports) {
195 - if (port.element().id().equals(virtualCp.elementId()) &&
196 - port.number().equals(virtualCp.port())) {
197 - return new ConnectPoint(port.realizedBy().element().id(), port.realizedBy().number());
198 - }
199 - }
200 - return null;
201 } 199 }
202 200
203 /** 201 /**
204 * Maps the physical connect point to a virtual connect point. 202 * Maps the physical connect point to a virtual connect point.
205 * 203 *
206 - * @param networkId network identifier 204 + * @param networkId network identifier
207 * @param physicalCp physical connect point 205 * @param physicalCp physical connect point
208 * @return virtual connect point 206 * @return virtual connect point
209 */ 207 */
210 private ConnectPoint mapPhysicalToVirtualToPort(NetworkId networkId, 208 private ConnectPoint mapPhysicalToVirtualToPort(NetworkId networkId,
211 - ConnectPoint physicalCp) { 209 + ConnectPoint physicalCp) {
212 Set<VirtualPort> ports = store.getPorts(networkId, null); 210 Set<VirtualPort> ports = store.getPorts(networkId, null);
213 for (VirtualPort port : ports) { 211 for (VirtualPort port : ports) {
214 if (port.realizedBy().element().id().equals(physicalCp.elementId()) && 212 if (port.realizedBy().element().id().equals(physicalCp.elementId()) &&
...@@ -224,14 +222,7 @@ public class VirtualNetworkManager ...@@ -224,14 +222,7 @@ public class VirtualNetworkManager
224 checkNotNull(networkId, NETWORK_NULL); 222 checkNotNull(networkId, NETWORK_NULL);
225 checkNotNull(src, LINK_POINT_NULL); 223 checkNotNull(src, LINK_POINT_NULL);
226 checkNotNull(dst, LINK_POINT_NULL); 224 checkNotNull(dst, LINK_POINT_NULL);
227 - VirtualLink virtualLink = store.removeLink(networkId, src, dst); 225 + store.removeLink(networkId, src, dst);
228 -
229 - if (virtualLink != null && virtualLink.providerId() != null) {
230 - VirtualNetworkProvider provider = getProvider(virtualLink.providerId());
231 - if (provider != null) {
232 - provider.destroyTunnel(networkId, virtualLink.tunnelId());
233 - }
234 - }
235 } 226 }
236 227
237 @Override 228 @Override
...@@ -257,6 +248,12 @@ public class VirtualNetworkManager ...@@ -257,6 +248,12 @@ public class VirtualNetworkManager
257 return store.getNetworks(tenantId); 248 return store.getNetworks(tenantId);
258 } 249 }
259 250
251 + /**
252 + * Returns the virtual network matching the network identifier.
253 + *
254 + * @param networkId network identifier
255 + * @return virtual network
256 + */
260 private VirtualNetwork getVirtualNetwork(NetworkId networkId) { 257 private VirtualNetwork getVirtualNetwork(NetworkId networkId) {
261 checkNotNull(networkId, NETWORK_NULL); 258 checkNotNull(networkId, NETWORK_NULL);
262 return store.getNetwork(networkId); 259 return store.getNetwork(networkId);
...@@ -299,17 +296,38 @@ public class VirtualNetworkManager ...@@ -299,17 +296,38 @@ public class VirtualNetworkManager
299 return (T) service; 296 return (T) service;
300 } 297 }
301 298
299 + /**
300 + * Returns the Vnet service matching the service key.
301 + *
302 + * @param serviceKey service key
303 + * @return vnet service
304 + */
302 private VnetService lookup(ServiceKey serviceKey) { 305 private VnetService lookup(ServiceKey serviceKey) {
303 return networkServices.get(serviceKey); 306 return networkServices.get(serviceKey);
304 } 307 }
305 308
309 + /**
310 + * Creates a new service key using the specified network identifier and service class.
311 + *
312 + * @param networkId network identifier
313 + * @param serviceClass service class
314 + * @param <T> type of service
315 + * @return service key
316 + */
306 private <T> ServiceKey networkServiceKey(NetworkId networkId, Class<T> serviceClass) { 317 private <T> ServiceKey networkServiceKey(NetworkId networkId, Class<T> serviceClass) {
307 return new ServiceKey(networkId, serviceClass); 318 return new ServiceKey(networkId, serviceClass);
308 } 319 }
309 320
310 321
322 + /**
323 + * Create a new vnet service instance.
324 + *
325 + * @param serviceKey service key
326 + * @return vnet service
327 + */
311 private VnetService create(ServiceKey serviceKey) { 328 private VnetService create(ServiceKey serviceKey) {
312 VirtualNetwork network = getVirtualNetwork(serviceKey.networkId()); 329 VirtualNetwork network = getVirtualNetwork(serviceKey.networkId());
330 + checkNotNull(network, NETWORK_NULL);
313 VnetService service; 331 VnetService service;
314 if (serviceKey.serviceClass.equals(DeviceService.class)) { 332 if (serviceKey.serviceClass.equals(DeviceService.class)) {
315 service = new VirtualNetworkDeviceService(this, network); 333 service = new VirtualNetworkDeviceService(this, network);
...@@ -317,6 +335,8 @@ public class VirtualNetworkManager ...@@ -317,6 +335,8 @@ public class VirtualNetworkManager
317 service = new VirtualNetworkLinkService(this, network); 335 service = new VirtualNetworkLinkService(this, network);
318 } else if (serviceKey.serviceClass.equals(TopologyService.class)) { 336 } else if (serviceKey.serviceClass.equals(TopologyService.class)) {
319 service = new VirtualNetworkTopologyService(this, network); 337 service = new VirtualNetworkTopologyService(this, network);
338 + } else if (serviceKey.serviceClass.equals(IntentService.class)) {
339 + service = new VirtualNetworkIntentService(this, network, new DefaultServiceDirectory());
320 } else { 340 } else {
321 return null; 341 return null;
322 } 342 }
...@@ -324,25 +344,94 @@ public class VirtualNetworkManager ...@@ -324,25 +344,94 @@ public class VirtualNetworkManager
324 return service; 344 return service;
325 } 345 }
326 346
347 + /**
348 + * Service key class.
349 + */
327 private class ServiceKey { 350 private class ServiceKey {
328 final NetworkId networkId; 351 final NetworkId networkId;
329 final Class serviceClass; 352 final Class serviceClass;
330 353
354 + /**
355 + * Constructor for service key.
356 + *
357 + * @param networkId network identifier
358 + * @param serviceClass service class
359 + */
331 public ServiceKey(NetworkId networkId, Class serviceClass) { 360 public ServiceKey(NetworkId networkId, Class serviceClass) {
332 checkNotNull(networkId, NETWORK_NULL); 361 checkNotNull(networkId, NETWORK_NULL);
333 this.networkId = networkId; 362 this.networkId = networkId;
334 this.serviceClass = serviceClass; 363 this.serviceClass = serviceClass;
335 } 364 }
336 365
366 + /**
367 + * Returns the network identifier.
368 + *
369 + * @return network identifier
370 + */
337 public NetworkId networkId() { 371 public NetworkId networkId() {
338 return networkId; 372 return networkId;
339 } 373 }
340 374
375 + /**
376 + * Returns the service class.
377 + *
378 + * @return service class
379 + */
341 public Class serviceClass() { 380 public Class serviceClass() {
342 return serviceClass; 381 return serviceClass;
343 } 382 }
344 } 383 }
345 384
385 + /**
386 + * Internal intent event listener.
387 + */
388 + private class InternalVirtualIntentListener implements IntentListener {
389 + @Override
390 + public void event(IntentEvent event) {
391 +
392 + // Ignore intent events that are not relevant.
393 + if (!isRelevant(event)) {
394 + return;
395 + }
396 +
397 + VirtualNetworkIntent intent = (VirtualNetworkIntent) event.subject();
398 +
399 + switch (event.type()) {
400 + case INSTALL_REQ:
401 + store.addOrUpdateIntent(intent, IntentState.INSTALL_REQ);
402 + break;
403 + case INSTALLED:
404 + store.addOrUpdateIntent(intent, IntentState.INSTALLED);
405 + break;
406 + case WITHDRAW_REQ:
407 + store.addOrUpdateIntent(intent, IntentState.WITHDRAW_REQ);
408 + break;
409 + case WITHDRAWN:
410 + store.addOrUpdateIntent(intent, IntentState.WITHDRAWN);
411 + break;
412 + case FAILED:
413 + store.addOrUpdateIntent(intent, IntentState.FAILED);
414 + break;
415 + case CORRUPT:
416 + store.addOrUpdateIntent(intent, IntentState.CORRUPT);
417 + break;
418 + case PURGED:
419 + store.removeIntent(intent.key());
420 + default:
421 + break;
422 + }
423 + }
424 +
425 + @Override
426 + public boolean isRelevant(IntentEvent event) {
427 + if (event.subject() instanceof VirtualNetworkIntent) {
428 + return true;
429 + }
430 + return false;
431 + }
432 + }
433 +
434 +
346 @Override 435 @Override
347 protected VirtualNetworkProviderService createProviderService(VirtualNetworkProvider provider) { 436 protected VirtualNetworkProviderService createProviderService(VirtualNetworkProvider provider) {
348 return new InternalVirtualNetworkProviderService(provider); 437 return new InternalVirtualNetworkProviderService(provider);
......
...@@ -38,6 +38,8 @@ import org.onosproject.net.Port; ...@@ -38,6 +38,8 @@ import org.onosproject.net.Port;
38 import org.onosproject.net.PortNumber; 38 import org.onosproject.net.PortNumber;
39 import org.onosproject.net.TestDeviceParams; 39 import org.onosproject.net.TestDeviceParams;
40 import org.onosproject.net.device.DeviceService; 40 import org.onosproject.net.device.DeviceService;
41 +import org.onosproject.net.intent.FakeIntentManager;
42 +import org.onosproject.net.intent.TestableIntentService;
41 import org.onosproject.store.service.TestStorageService; 43 import org.onosproject.store.service.TestStorageService;
42 44
43 import java.util.Iterator; 45 import java.util.Iterator;
...@@ -54,6 +56,7 @@ public class VirtualNetworkDeviceServiceTest extends TestDeviceParams { ...@@ -54,6 +56,7 @@ public class VirtualNetworkDeviceServiceTest extends TestDeviceParams {
54 private VirtualNetworkManager manager; 56 private VirtualNetworkManager manager;
55 private DistributedVirtualNetworkStore virtualNetworkManagerStore; 57 private DistributedVirtualNetworkStore virtualNetworkManagerStore;
56 private CoreService coreService; 58 private CoreService coreService;
59 + private TestableIntentService intentService = new FakeIntentManager();
57 60
58 @Before 61 @Before
59 public void setUp() throws Exception { 62 public void setUp() throws Exception {
...@@ -67,6 +70,7 @@ public class VirtualNetworkDeviceServiceTest extends TestDeviceParams { ...@@ -67,6 +70,7 @@ public class VirtualNetworkDeviceServiceTest extends TestDeviceParams {
67 70
68 manager = new VirtualNetworkManager(); 71 manager = new VirtualNetworkManager();
69 manager.store = virtualNetworkManagerStore; 72 manager.store = virtualNetworkManagerStore;
73 + manager.intentService = intentService;
70 NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher()); 74 NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
71 manager.activate(); 75 manager.activate();
72 } 76 }
......
1 +/*
2 + * Copyright 2016-present 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 +
17 +package org.onosproject.incubator.net.virtual.impl;
18 +
19 +import com.google.common.collect.Iterators;
20 +import com.google.common.collect.Lists;
21 +import org.junit.After;
22 +import org.junit.Before;
23 +import org.junit.Test;
24 +import org.onlab.junit.TestUtils;
25 +import org.onlab.osgi.ServiceDirectory;
26 +import org.onlab.osgi.TestServiceDirectory;
27 +import org.onlab.rest.BaseResource;
28 +import org.onosproject.TestApplicationId;
29 +import org.onosproject.common.event.impl.TestEventDispatcher;
30 +import org.onosproject.core.ApplicationId;
31 +import org.onosproject.core.CoreService;
32 +import org.onosproject.core.CoreServiceAdapter;
33 +import org.onosproject.core.IdGenerator;
34 +import org.onosproject.incubator.net.virtual.TenantId;
35 +import org.onosproject.incubator.net.virtual.VirtualDevice;
36 +import org.onosproject.incubator.net.virtual.VirtualLink;
37 +import org.onosproject.incubator.net.virtual.VirtualNetwork;
38 +import org.onosproject.incubator.net.virtual.VirtualNetworkIntent;
39 +import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
40 +import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore;
41 +import org.onosproject.net.ConnectPoint;
42 +import org.onosproject.net.DefaultPort;
43 +import org.onosproject.net.EncapsulationType;
44 +import org.onosproject.net.Link;
45 +import org.onosproject.net.NetTestTools;
46 +import org.onosproject.net.Port;
47 +import org.onosproject.net.PortNumber;
48 +import org.onosproject.net.TestDeviceParams;
49 +import org.onosproject.net.intent.Constraint;
50 +import org.onosproject.net.intent.FakeIntentManager;
51 +import org.onosproject.net.intent.FlowRuleIntent;
52 +import org.onosproject.net.intent.Intent;
53 +import org.onosproject.net.intent.IntentCompiler;
54 +import org.onosproject.net.intent.IntentEvent;
55 +import org.onosproject.net.intent.IntentExtensionService;
56 +import org.onosproject.net.intent.IntentListener;
57 +import org.onosproject.net.intent.IntentPartitionService;
58 +import org.onosproject.net.intent.IntentPartitionServiceAdapter;
59 +import org.onosproject.net.intent.IntentService;
60 +import org.onosproject.net.intent.IntentState;
61 +import org.onosproject.net.intent.IntentTestsMocks;
62 +import org.onosproject.net.intent.Key;
63 +import org.onosproject.net.intent.MockIdGenerator;
64 +import org.onosproject.net.intent.TestableIntentService;
65 +import org.onosproject.net.intent.constraint.EncapsulationConstraint;
66 +import org.onosproject.store.service.TestStorageService;
67 +
68 +import java.util.ArrayList;
69 +import java.util.Collections;
70 +import java.util.List;
71 +import java.util.concurrent.Semaphore;
72 +import java.util.concurrent.TimeUnit;
73 +import java.util.concurrent.atomic.AtomicLong;
74 +
75 +import static org.junit.Assert.*;
76 +
77 +/**
78 + * Junit tests for VirtualNetworkIntentService.
79 + */
80 +public class VirtualNetworkIntentServiceTest extends TestDeviceParams {
81 +
82 + private final String tenantIdValue1 = "TENANT_ID1";
83 + private static final ApplicationId APP_ID =
84 + new TestApplicationId(PtToPtIntentVirtualNetworkProvider.PTPT_INTENT_APPID);
85 +
86 + private ConnectPoint cp1;
87 + private ConnectPoint cp2;
88 + private ConnectPoint cp3;
89 + private ConnectPoint cp4;
90 + private ConnectPoint cp5;
91 + private ConnectPoint cp6;
92 + private VirtualLink link1;
93 + private VirtualLink link2;
94 + private VirtualLink link3;
95 + private VirtualLink link4;
96 + private VirtualLink link5;
97 + private VirtualLink link6;
98 +
99 + private VirtualNetworkManager manager;
100 + private static DistributedVirtualNetworkStore virtualNetworkManagerStore;
101 + private CoreService coreService;
102 + private TestableIntentService intentService = new FakeIntentManager();
103 + private VirtualNetworkIntentService vnetIntentService;
104 + private TestIntentCompiler compiler = new TestIntentCompiler();
105 + private IntentExtensionService intentExtensionService;
106 + private IntentPartitionService intentPartitionService;
107 + private ServiceDirectory testDirectory;
108 + private TestListener listener = new TestListener();
109 + private IdGenerator idGenerator = new MockIdGenerator();
110 + private static final int MAX_WAIT_TIME = 5;
111 + private static final int MAX_PERMITS = 1;
112 + private static Semaphore created;
113 + private static Semaphore withdrawn;
114 + private static Semaphore purged;
115 +
116 + @Before
117 + public void setUp() throws Exception {
118 + virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
119 +
120 + coreService = new VirtualNetworkIntentServiceTest.TestCoreService();
121 +
122 + Intent.unbindIdGenerator(idGenerator);
123 + Intent.bindIdGenerator(idGenerator);
124 +
125 + virtualNetworkManagerStore.setCoreService(coreService);
126 + TestUtils.setField(coreService, "coreService", new VirtualNetworkIntentServiceTest.TestCoreService());
127 + TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
128 + virtualNetworkManagerStore.activate();
129 +
130 + manager = new VirtualNetworkManager();
131 + manager.store = virtualNetworkManagerStore;
132 + NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
133 + manager.intentService = intentService;
134 + manager.activate();
135 + intentService.addListener(listener);
136 +
137 + // Register a compiler and an installer both setup for success.
138 + intentExtensionService = intentService;
139 + intentExtensionService.registerCompiler(VirtualNetworkIntent.class, compiler);
140 +
141 + created = new Semaphore(0, true);
142 + withdrawn = new Semaphore(0, true);
143 + purged = new Semaphore(0, true);
144 +
145 + intentPartitionService = new IntentPartitionServiceAdapter();
146 + testDirectory = new TestServiceDirectory()
147 + .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
148 + .add(IntentService.class, intentService)
149 + .add(IntentPartitionService.class, intentPartitionService);
150 + BaseResource.setServiceDirectory(testDirectory);
151 + }
152 +
153 + @After
154 + public void tearDown() {
155 + virtualNetworkManagerStore.deactivate();
156 + manager.deactivate();
157 + NetTestTools.injectEventDispatcher(manager, null);
158 + Intent.unbindIdGenerator(idGenerator);
159 + intentService.removeListener(listener);
160 + created = null;
161 + withdrawn = null;
162 + purged = null;
163 + }
164 +
165 + /**
166 + * Method to create the virtual network for further testing.
167 + *
168 + * @return virtual network
169 + */
170 + private VirtualNetwork setupVirtualNetworkTopology() {
171 + manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
172 + VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
173 + VirtualDevice virtualDevice1 =
174 + manager.createVirtualDevice(virtualNetwork.id(), DID1);
175 + VirtualDevice virtualDevice2 =
176 + manager.createVirtualDevice(virtualNetwork.id(), DID2);
177 + VirtualDevice virtualDevice3 =
178 + manager.createVirtualDevice(virtualNetwork.id(), DID3);
179 + VirtualDevice virtualDevice4 =
180 + manager.createVirtualDevice(virtualNetwork.id(), DID4);
181 +
182 + Port port1 = new DefaultPort(virtualDevice1, PortNumber.portNumber(1), true);
183 + manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(), port1.number(), port1);
184 + cp1 = new ConnectPoint(virtualDevice1.id(), port1.number());
185 +
186 + Port port2 = new DefaultPort(virtualDevice1, PortNumber.portNumber(2), true);
187 + manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(), port2.number(), port2);
188 + cp2 = new ConnectPoint(virtualDevice1.id(), port2.number());
189 +
190 + Port port3 = new DefaultPort(virtualDevice2, PortNumber.portNumber(3), true);
191 + manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(), port3.number(), port3);
192 + cp3 = new ConnectPoint(virtualDevice2.id(), port3.number());
193 +
194 + Port port4 = new DefaultPort(virtualDevice2, PortNumber.portNumber(4), true);
195 + manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(), port4.number(), port4);
196 + cp4 = new ConnectPoint(virtualDevice2.id(), port4.number());
197 +
198 + Port port5 = new DefaultPort(virtualDevice3, PortNumber.portNumber(5), true);
199 + manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(), port5.number(), port5);
200 + cp5 = new ConnectPoint(virtualDevice3.id(), port5.number());
201 +
202 + Port port6 = new DefaultPort(virtualDevice3, PortNumber.portNumber(6), true);
203 + manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(), port6.number(), port6);
204 + cp6 = new ConnectPoint(virtualDevice3.id(), port6.number());
205 +
206 + link1 = manager.createVirtualLink(virtualNetwork.id(), cp1, cp3);
207 + virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
208 + link2 = manager.createVirtualLink(virtualNetwork.id(), cp3, cp1);
209 + virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
210 + link3 = manager.createVirtualLink(virtualNetwork.id(), cp4, cp5);
211 + virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE);
212 + link4 = manager.createVirtualLink(virtualNetwork.id(), cp5, cp4);
213 + virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE);
214 +
215 + vnetIntentService = new VirtualNetworkIntentService(manager, virtualNetwork, testDirectory);
216 + vnetIntentService.intentService = intentService;
217 + vnetIntentService.store = virtualNetworkManagerStore;
218 + vnetIntentService.partitionService = intentPartitionService;
219 + return virtualNetwork;
220 + }
221 +
222 + /**
223 + * Tests the submit(), withdraw(), and purge() methods.
224 + */
225 + @Test
226 + public void testCreateAndRemoveIntent() {
227 + VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
228 +
229 + Key intentKey = Key.of("test", APP_ID);
230 +
231 + List<Constraint> constraints = new ArrayList<>();
232 + constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN));
233 +
234 + VirtualNetworkIntent virtualIntent = VirtualNetworkIntent.builder()
235 + .networkId(virtualNetwork.id())
236 + .key(intentKey)
237 + .appId(APP_ID)
238 + .ingressPoint(cp1)
239 + .egressPoint(cp5)
240 + .constraints(constraints)
241 + .build();
242 + // Test the submit() method.
243 + vnetIntentService.submit(virtualIntent);
244 +
245 + // Wait for the both intents to go into an INSTALLED state.
246 + try {
247 + if (!created.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
248 + fail("Failed to wait for intent to get installed.");
249 + }
250 + } catch (InterruptedException e) {
251 + fail("Semaphore exception during intent installation." + e.getMessage());
252 + }
253 +
254 + // Test the getIntentState() method
255 + assertEquals("The intent state did not match as expected.", IntentState.INSTALLED,
256 + vnetIntentService.getIntentState(virtualIntent.key()));
257 +
258 + // Test the withdraw() method.
259 + vnetIntentService.withdraw(virtualIntent);
260 + // Wait for the both intents to go into a WITHDRAWN state.
261 + try {
262 + if (!withdrawn.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
263 + fail("Failed to wait for intent to get withdrawn.");
264 + }
265 + } catch (InterruptedException e) {
266 + fail("Semaphore exception during intent withdrawal." + e.getMessage());
267 + }
268 +
269 + // Test the getIntentState() method
270 + assertEquals("The intent state did not match as expected.", IntentState.WITHDRAWN,
271 + vnetIntentService.getIntentState(virtualIntent.key()));
272 +
273 + // Test the purge() method.
274 + vnetIntentService.purge(virtualIntent);
275 + // Wait for the both intents to be removed/purged.
276 + try {
277 + if (!purged.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
278 + fail("Failed to wait for intent to get purged.");
279 + }
280 + } catch (InterruptedException e) {
281 + fail("Semaphore exception during intent purging." + e.getMessage());
282 + }
283 +
284 + }
285 +
286 + /**
287 + * Tests the getIntents, getIntent(), getIntentData(), getIntentCount(),
288 + * isLocal() methods.
289 + */
290 + @Test
291 + public void testGetIntents() {
292 + VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
293 +
294 + Key intentKey = Key.of("test", APP_ID);
295 +
296 + List<Constraint> constraints = new ArrayList<>();
297 + constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN));
298 +
299 + VirtualNetworkIntent virtualIntent = VirtualNetworkIntent.builder()
300 + .networkId(virtualNetwork.id())
301 + .key(intentKey)
302 + .appId(APP_ID)
303 + .ingressPoint(cp1)
304 + .egressPoint(cp5)
305 + .constraints(constraints)
306 + .build();
307 + // Test the submit() method.
308 + vnetIntentService.submit(virtualIntent);
309 +
310 + // Wait for the both intents to go into an INSTALLED state.
311 + try {
312 + if (!created.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
313 + fail("Failed to wait for intent to get installed.");
314 + }
315 + } catch (InterruptedException e) {
316 + fail("Semaphore exception during intent installation." + e.getMessage());
317 + }
318 +
319 + // Test the getIntents() method
320 + assertEquals("The intents size did not match as expected.", 1,
321 + Iterators.size(vnetIntentService.getIntents().iterator()));
322 +
323 + // Test the getIntent() method
324 + assertNotNull("The intent should have been found.", vnetIntentService.getIntent(virtualIntent.key()));
325 +
326 + // Test the getIntentData() method
327 + assertEquals("The intent data size did not match as expected.", 1,
328 + Iterators.size(vnetIntentService.getIntentData().iterator()));
329 +
330 + // Test the getIntentCount() method
331 + assertEquals("The intent count did not match as expected.", 1,
332 + vnetIntentService.getIntentCount());
333 +
334 + // Test the isLocal() method
335 + assertTrue("The intent should be local.", vnetIntentService.isLocal(virtualIntent.key()));
336 +
337 + }
338 +
339 + /**
340 + * Test listener to listen for intent events.
341 + */
342 + private static class TestListener implements IntentListener {
343 +
344 + @Override
345 + public void event(IntentEvent event) {
346 + switch (event.type()) {
347 + case INSTALLED:
348 + // Release one permit on the created semaphore since the Intent event was received.
349 + virtualNetworkManagerStore.addOrUpdateIntent(event.subject(), IntentState.INSTALLED);
350 + created.release();
351 + break;
352 + case WITHDRAWN:
353 + // Release one permit on the removed semaphore since the Intent event was received.
354 + virtualNetworkManagerStore.addOrUpdateIntent(event.subject(), IntentState.WITHDRAWN);
355 + withdrawn.release();
356 + break;
357 + case PURGED:
358 + // Release one permit on the purged semaphore since the Intent event was received.
359 + purged.release();
360 + break;
361 + default:
362 + break;
363 + }
364 + }
365 + }
366 +
367 + /**
368 + * Core service test class.
369 + */
370 + private class TestCoreService extends CoreServiceAdapter {
371 +
372 + @Override
373 + public IdGenerator getIdGenerator(String topic) {
374 + return new IdGenerator() {
375 + private AtomicLong counter = new AtomicLong(0);
376 +
377 + @Override
378 + public long getNewId() {
379 + return counter.getAndIncrement();
380 + }
381 + };
382 + }
383 + }
384 +
385 + private static class TestIntentCompiler implements IntentCompiler<VirtualNetworkIntent> {
386 + @Override
387 + public List<Intent> compile(VirtualNetworkIntent intent, List<Intent> installable) {
388 + return Lists.newArrayList(new MockInstallableIntent());
389 + }
390 + }
391 +
392 + private static class MockInstallableIntent extends FlowRuleIntent {
393 +
394 + public MockInstallableIntent() {
395 + super(APP_ID, Collections.singletonList(new IntentTestsMocks.MockFlowRule(100)), Collections.emptyList());
396 + }
397 + }
398 +}
...@@ -35,6 +35,8 @@ import org.onosproject.net.Link; ...@@ -35,6 +35,8 @@ import org.onosproject.net.Link;
35 import org.onosproject.net.NetTestTools; 35 import org.onosproject.net.NetTestTools;
36 import org.onosproject.net.PortNumber; 36 import org.onosproject.net.PortNumber;
37 import org.onosproject.net.TestDeviceParams; 37 import org.onosproject.net.TestDeviceParams;
38 +import org.onosproject.net.intent.FakeIntentManager;
39 +import org.onosproject.net.intent.TestableIntentService;
38 import org.onosproject.net.link.LinkService; 40 import org.onosproject.net.link.LinkService;
39 import org.onosproject.store.service.TestStorageService; 41 import org.onosproject.store.service.TestStorageService;
40 42
...@@ -54,6 +56,7 @@ public class VirtualNetworkLinkServiceTest extends TestDeviceParams { ...@@ -54,6 +56,7 @@ public class VirtualNetworkLinkServiceTest extends TestDeviceParams {
54 private VirtualNetworkManager manager; 56 private VirtualNetworkManager manager;
55 private DistributedVirtualNetworkStore virtualNetworkManagerStore; 57 private DistributedVirtualNetworkStore virtualNetworkManagerStore;
56 private CoreService coreService; 58 private CoreService coreService;
59 + private TestableIntentService intentService = new FakeIntentManager();
57 60
58 @Before 61 @Before
59 public void setUp() throws Exception { 62 public void setUp() throws Exception {
...@@ -67,6 +70,7 @@ public class VirtualNetworkLinkServiceTest extends TestDeviceParams { ...@@ -67,6 +70,7 @@ public class VirtualNetworkLinkServiceTest extends TestDeviceParams {
67 70
68 manager = new VirtualNetworkManager(); 71 manager = new VirtualNetworkManager();
69 manager.store = virtualNetworkManagerStore; 72 manager.store = virtualNetworkManagerStore;
73 + manager.intentService = intentService;
70 NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher()); 74 NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
71 manager.activate(); 75 manager.activate();
72 } 76 }
...@@ -103,12 +107,12 @@ public class VirtualNetworkLinkServiceTest extends TestDeviceParams { ...@@ -103,12 +107,12 @@ public class VirtualNetworkLinkServiceTest extends TestDeviceParams {
103 Iterator<Link> it = linkService.getLinks().iterator(); 107 Iterator<Link> it = linkService.getLinks().iterator();
104 assertEquals("The link set size did not match.", 2, Iterators.size(it)); 108 assertEquals("The link set size did not match.", 2, Iterators.size(it));
105 109
106 - // test the getActiveLinks() method where no links are ACTIVE 110 + // test the getActiveLinks() method where all links are ACTIVE
107 Iterator<Link> it2 = linkService.getActiveLinks().iterator(); 111 Iterator<Link> it2 = linkService.getActiveLinks().iterator();
108 - assertEquals("The link set size did not match.", 0, Iterators.size(it2)); 112 + assertEquals("The link set size did not match.", 2, Iterators.size(it2));
109 113
110 // test the getActiveLinks() method where one link is ACTIVE 114 // test the getActiveLinks() method where one link is ACTIVE
111 - virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE); 115 + virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.INACTIVE);
112 Iterator<Link> it3 = linkService.getActiveLinks().iterator(); 116 Iterator<Link> it3 = linkService.getActiveLinks().iterator();
113 assertEquals("The link set size did not match.", 1, Iterators.size(it3)); 117 assertEquals("The link set size did not match.", 1, Iterators.size(it3));
114 118
......
...@@ -27,6 +27,7 @@ import org.onosproject.core.CoreService; ...@@ -27,6 +27,7 @@ import org.onosproject.core.CoreService;
27 import org.onosproject.core.CoreServiceAdapter; 27 import org.onosproject.core.CoreServiceAdapter;
28 import org.onosproject.core.IdGenerator; 28 import org.onosproject.core.IdGenerator;
29 import org.onosproject.event.Event; 29 import org.onosproject.event.Event;
30 +import org.onosproject.incubator.net.tunnel.TunnelId;
30 import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork; 31 import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork;
31 import org.onosproject.incubator.net.virtual.NetworkId; 32 import org.onosproject.incubator.net.virtual.NetworkId;
32 import org.onosproject.incubator.net.virtual.TenantId; 33 import org.onosproject.incubator.net.virtual.TenantId;
...@@ -35,6 +36,7 @@ import org.onosproject.incubator.net.virtual.VirtualHost; ...@@ -35,6 +36,7 @@ import org.onosproject.incubator.net.virtual.VirtualHost;
35 import org.onosproject.incubator.net.virtual.VirtualLink; 36 import org.onosproject.incubator.net.virtual.VirtualLink;
36 import org.onosproject.incubator.net.virtual.VirtualNetwork; 37 import org.onosproject.incubator.net.virtual.VirtualNetwork;
37 import org.onosproject.incubator.net.virtual.VirtualNetworkEvent; 38 import org.onosproject.incubator.net.virtual.VirtualNetworkEvent;
39 +import org.onosproject.incubator.net.virtual.VirtualNetworkIntent;
38 import org.onosproject.incubator.net.virtual.VirtualNetworkListener; 40 import org.onosproject.incubator.net.virtual.VirtualNetworkListener;
39 import org.onosproject.incubator.net.virtual.VirtualNetworkService; 41 import org.onosproject.incubator.net.virtual.VirtualNetworkService;
40 import org.onosproject.incubator.net.virtual.VirtualPort; 42 import org.onosproject.incubator.net.virtual.VirtualPort;
...@@ -46,6 +48,12 @@ import org.onosproject.net.NetTestTools; ...@@ -46,6 +48,12 @@ import org.onosproject.net.NetTestTools;
46 import org.onosproject.net.Port; 48 import org.onosproject.net.Port;
47 import org.onosproject.net.PortNumber; 49 import org.onosproject.net.PortNumber;
48 import org.onosproject.net.TestDeviceParams; 50 import org.onosproject.net.TestDeviceParams;
51 +import org.onosproject.net.intent.FakeIntentManager;
52 +import org.onosproject.net.intent.Intent;
53 +import org.onosproject.net.intent.IntentState;
54 +import org.onosproject.net.intent.Key;
55 +import org.onosproject.net.intent.MockIdGenerator;
56 +import org.onosproject.net.intent.TestableIntentService;
49 import org.onosproject.store.service.TestStorageService; 57 import org.onosproject.store.service.TestStorageService;
50 58
51 import java.util.Collection; 59 import java.util.Collection;
...@@ -54,6 +62,7 @@ import java.util.Set; ...@@ -54,6 +62,7 @@ import java.util.Set;
54 import java.util.concurrent.atomic.AtomicLong; 62 import java.util.concurrent.atomic.AtomicLong;
55 63
56 import static org.junit.Assert.*; 64 import static org.junit.Assert.*;
65 +import static org.onosproject.net.NetTestTools.APP_ID;
57 66
58 /** 67 /**
59 * Junit tests for VirtualNetworkManager. 68 * Junit tests for VirtualNetworkManager.
...@@ -67,10 +76,13 @@ public class VirtualNetworkManagerTest extends TestDeviceParams { ...@@ -67,10 +76,13 @@ public class VirtualNetworkManagerTest extends TestDeviceParams {
67 private DistributedVirtualNetworkStore virtualNetworkManagerStore; 76 private DistributedVirtualNetworkStore virtualNetworkManagerStore;
68 private CoreService coreService; 77 private CoreService coreService;
69 private TestListener listener = new TestListener(); 78 private TestListener listener = new TestListener();
79 + private TestableIntentService intentService = new FakeIntentManager();
80 + private IdGenerator idGenerator = new MockIdGenerator();
70 81
71 @Before 82 @Before
72 public void setUp() throws Exception { 83 public void setUp() throws Exception {
73 virtualNetworkManagerStore = new DistributedVirtualNetworkStore(); 84 virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
85 + Intent.bindIdGenerator(idGenerator);
74 86
75 coreService = new TestCoreService(); 87 coreService = new TestCoreService();
76 virtualNetworkManagerStore.setCoreService(coreService); 88 virtualNetworkManagerStore.setCoreService(coreService);
...@@ -81,6 +93,7 @@ public class VirtualNetworkManagerTest extends TestDeviceParams { ...@@ -81,6 +93,7 @@ public class VirtualNetworkManagerTest extends TestDeviceParams {
81 manager = new VirtualNetworkManager(); 93 manager = new VirtualNetworkManager();
82 manager.store = virtualNetworkManagerStore; 94 manager.store = virtualNetworkManagerStore;
83 manager.addListener(listener); 95 manager.addListener(listener);
96 + manager.intentService = intentService;
84 NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher()); 97 NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
85 manager.activate(); 98 manager.activate();
86 virtualNetworkManagerService = manager; 99 virtualNetworkManagerService = manager;
...@@ -92,6 +105,7 @@ public class VirtualNetworkManagerTest extends TestDeviceParams { ...@@ -92,6 +105,7 @@ public class VirtualNetworkManagerTest extends TestDeviceParams {
92 manager.removeListener(listener); 105 manager.removeListener(listener);
93 manager.deactivate(); 106 manager.deactivate();
94 NetTestTools.injectEventDispatcher(manager, null); 107 NetTestTools.injectEventDispatcher(manager, null);
108 + Intent.unbindIdGenerator(idGenerator);
95 } 109 }
96 110
97 /** 111 /**
...@@ -377,6 +391,95 @@ public class VirtualNetworkManagerTest extends TestDeviceParams { ...@@ -377,6 +391,95 @@ public class VirtualNetworkManagerTest extends TestDeviceParams {
377 } 391 }
378 392
379 /** 393 /**
394 + * Tests the addOrUpdateIntent() method in the store with a null intent.
395 + */
396 + @Test(expected = NullPointerException.class)
397 + public void testAddOrUpdateNullIntent() {
398 + manager.store.addOrUpdateIntent(null, null);
399 + }
400 +
401 + /**
402 + * Tests the removeIntent() method in the store with a null intent key.
403 + */
404 + @Test(expected = NullPointerException.class)
405 + public void testRemoveNullIntentKey() {
406 + manager.store.removeIntent(null);
407 + }
408 +
409 + /**
410 + * Tests the addOrUpdateIntent(), getIntents(), getIntent(), removeIntent() methods with the store.
411 + */
412 + @Test
413 + public void testAddOrUpdateIntent() {
414 + manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
415 + VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
416 + ConnectPoint cp1 = new ConnectPoint(DID1, P1);
417 + ConnectPoint cp2 = new ConnectPoint(DID2, P1);
418 +
419 + VirtualNetworkIntent virtualIntent = VirtualNetworkIntent.builder()
420 + .networkId(virtualNetwork.id())
421 + .key(Key.of("Test", APP_ID))
422 + .appId(APP_ID)
423 + .ingressPoint(cp1)
424 + .egressPoint(cp2)
425 + .build();
426 +
427 + // Add the intent to the store.
428 + manager.store.addOrUpdateIntent(virtualIntent, IntentState.INSTALL_REQ);
429 + assertEquals("The intent size should match.", 1, manager.store.getIntents().size());
430 + assertNotNull("The intent should not be null.", manager.store.getIntent(virtualIntent.key()));
431 +
432 + // remove the intent from the store.
433 + manager.store.removeIntent(virtualIntent.key());
434 + assertTrue("The intents should be empty.", manager.store.getIntents().isEmpty());
435 + assertNull("The intent should be null.", manager.store.getIntent(virtualIntent.key()));
436 + }
437 +
438 + /**
439 + * Tests the addTunnelId() method in the store with a null intent.
440 + */
441 + @Test(expected = NullPointerException.class)
442 + public void testAddTunnelIdNullIntent() {
443 + manager.store.addTunnelId(null, null);
444 + }
445 +
446 + /**
447 + * Tests the removeTunnelId() method in the store with a null intent.
448 + */
449 + @Test(expected = NullPointerException.class)
450 + public void testRemoveTunnelIdNullIntent() {
451 + manager.store.removeTunnelId(null, null);
452 + }
453 +
454 + /**
455 + * Tests the addTunnelId, getTunnelIds(), removeTunnelId() methods with the store.
456 + */
457 + @Test
458 + public void testAddTunnelId() {
459 + manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
460 + VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
461 + ConnectPoint cp1 = new ConnectPoint(DID1, P1);
462 + ConnectPoint cp2 = new ConnectPoint(DID2, P1);
463 +
464 + VirtualNetworkIntent virtualIntent = VirtualNetworkIntent.builder()
465 + .networkId(virtualNetwork.id())
466 + .key(Key.of("Test", APP_ID))
467 + .appId(APP_ID)
468 + .ingressPoint(cp1)
469 + .egressPoint(cp2)
470 + .build();
471 +
472 + TunnelId tunnelId = TunnelId.valueOf("virtual tunnel");
473 + // Add the intent to tunnelID mapping to the store.
474 + manager.store.addTunnelId(virtualIntent, tunnelId);
475 + assertEquals("The tunnels size should match.", 1, manager.store.getTunnelIds(virtualIntent).size());
476 +
477 + // Remove the intent to tunnelID mapping from the store.
478 + manager.store.removeTunnelId(virtualIntent, tunnelId);
479 + assertTrue("The tunnels should be empty.", manager.store.getTunnelIds(virtualIntent).isEmpty());
480 + }
481 +
482 + /**
380 * Method to validate that the actual versus expected virtual network events were 483 * Method to validate that the actual versus expected virtual network events were
381 * received correctly. 484 * received correctly.
382 * 485 *
......
...@@ -38,6 +38,8 @@ import org.onosproject.net.NetTestTools; ...@@ -38,6 +38,8 @@ import org.onosproject.net.NetTestTools;
38 import org.onosproject.net.Path; 38 import org.onosproject.net.Path;
39 import org.onosproject.net.PortNumber; 39 import org.onosproject.net.PortNumber;
40 import org.onosproject.net.TestDeviceParams; 40 import org.onosproject.net.TestDeviceParams;
41 +import org.onosproject.net.intent.FakeIntentManager;
42 +import org.onosproject.net.intent.TestableIntentService;
41 import org.onosproject.net.topology.LinkWeight; 43 import org.onosproject.net.topology.LinkWeight;
42 import org.onosproject.net.topology.Topology; 44 import org.onosproject.net.topology.Topology;
43 import org.onosproject.net.topology.TopologyCluster; 45 import org.onosproject.net.topology.TopologyCluster;
...@@ -62,6 +64,7 @@ public class VirtualNetworkTopologyServiceTest extends TestDeviceParams { ...@@ -62,6 +64,7 @@ public class VirtualNetworkTopologyServiceTest extends TestDeviceParams {
62 private VirtualNetworkManager manager; 64 private VirtualNetworkManager manager;
63 private DistributedVirtualNetworkStore virtualNetworkManagerStore; 65 private DistributedVirtualNetworkStore virtualNetworkManagerStore;
64 private CoreService coreService; 66 private CoreService coreService;
67 + private TestableIntentService intentService = new FakeIntentManager();
65 68
66 @Before 69 @Before
67 public void setUp() throws Exception { 70 public void setUp() throws Exception {
...@@ -75,6 +78,7 @@ public class VirtualNetworkTopologyServiceTest extends TestDeviceParams { ...@@ -75,6 +78,7 @@ public class VirtualNetworkTopologyServiceTest extends TestDeviceParams {
75 78
76 manager = new VirtualNetworkManager(); 79 manager = new VirtualNetworkManager();
77 manager.store = virtualNetworkManagerStore; 80 manager.store = virtualNetworkManagerStore;
81 + manager.intentService = intentService;
78 NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher()); 82 NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
79 manager.activate(); 83 manager.activate();
80 } 84 }
......
...@@ -42,6 +42,7 @@ import org.onosproject.incubator.net.virtual.VirtualHost; ...@@ -42,6 +42,7 @@ import org.onosproject.incubator.net.virtual.VirtualHost;
42 import org.onosproject.incubator.net.virtual.VirtualLink; 42 import org.onosproject.incubator.net.virtual.VirtualLink;
43 import org.onosproject.incubator.net.virtual.VirtualNetwork; 43 import org.onosproject.incubator.net.virtual.VirtualNetwork;
44 import org.onosproject.incubator.net.virtual.VirtualNetworkEvent; 44 import org.onosproject.incubator.net.virtual.VirtualNetworkEvent;
45 +import org.onosproject.incubator.net.virtual.VirtualNetworkIntent;
45 import org.onosproject.incubator.net.virtual.VirtualNetworkService; 46 import org.onosproject.incubator.net.virtual.VirtualNetworkService;
46 import org.onosproject.incubator.net.virtual.VirtualNetworkStore; 47 import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
47 import org.onosproject.incubator.net.virtual.VirtualNetworkStoreDelegate; 48 import org.onosproject.incubator.net.virtual.VirtualNetworkStoreDelegate;
...@@ -54,6 +55,10 @@ import org.onosproject.net.HostLocation; ...@@ -54,6 +55,10 @@ import org.onosproject.net.HostLocation;
54 import org.onosproject.net.Link; 55 import org.onosproject.net.Link;
55 import org.onosproject.net.Port; 56 import org.onosproject.net.Port;
56 import org.onosproject.net.PortNumber; 57 import org.onosproject.net.PortNumber;
58 +import org.onosproject.net.intent.Intent;
59 +import org.onosproject.net.intent.IntentData;
60 +import org.onosproject.net.intent.IntentState;
61 +import org.onosproject.net.intent.Key;
57 import org.onosproject.store.AbstractStore; 62 import org.onosproject.store.AbstractStore;
58 import org.onosproject.store.serializers.KryoNamespaces; 63 import org.onosproject.store.serializers.KryoNamespaces;
59 import org.onosproject.store.service.ConsistentMap; 64 import org.onosproject.store.service.ConsistentMap;
...@@ -64,6 +69,7 @@ import org.onosproject.store.service.Serializer; ...@@ -64,6 +69,7 @@ import org.onosproject.store.service.Serializer;
64 import org.onosproject.store.service.SetEvent; 69 import org.onosproject.store.service.SetEvent;
65 import org.onosproject.store.service.SetEventListener; 70 import org.onosproject.store.service.SetEventListener;
66 import org.onosproject.store.service.StorageService; 71 import org.onosproject.store.service.StorageService;
72 +import org.onosproject.store.service.WallClockTimestamp;
67 import org.slf4j.Logger; 73 import org.slf4j.Logger;
68 74
69 import java.util.HashSet; 75 import java.util.HashSet;
...@@ -134,6 +140,14 @@ public class DistributedVirtualNetworkStore ...@@ -134,6 +140,14 @@ public class DistributedVirtualNetworkStore
134 private ConsistentMap<NetworkId, Set<VirtualPort>> networkIdVirtualPortSetConsistentMap; 140 private ConsistentMap<NetworkId, Set<VirtualPort>> networkIdVirtualPortSetConsistentMap;
135 private Map<NetworkId, Set<VirtualPort>> networkIdVirtualPortSetMap; 141 private Map<NetworkId, Set<VirtualPort>> networkIdVirtualPortSetMap;
136 142
143 + // Track intent key to intent data
144 + private ConsistentMap<Key, IntentData> intentKeyIntentDataConsistentMap;
145 + private Map<Key, IntentData> intentKeyIntentDataMap;
146 +
147 + // Track intent ID to TunnelIds
148 + private ConsistentMap<Key, Set<TunnelId>> intentKeyTunnelIdSetConsistentMap;
149 + private Map<Key, Set<TunnelId>> intentKeyTunnelIdSetMap;
150 +
137 private static final Serializer SERIALIZER = Serializer 151 private static final Serializer SERIALIZER = Serializer
138 .using(new KryoNamespace.Builder().register(KryoNamespaces.API) 152 .using(new KryoNamespace.Builder().register(KryoNamespaces.API)
139 .register(TenantId.class) 153 .register(TenantId.class)
...@@ -150,8 +164,11 @@ public class DistributedVirtualNetworkStore ...@@ -150,8 +164,11 @@ public class DistributedVirtualNetworkStore
150 .register(DefaultVirtualPort.class) 164 .register(DefaultVirtualPort.class)
151 .register(Device.class) 165 .register(Device.class)
152 .register(TunnelId.class) 166 .register(TunnelId.class)
167 + .register(IntentData.class)
168 + .register(VirtualNetworkIntent.class)
169 + .register(WallClockTimestamp.class)
153 .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID) 170 .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID)
154 - .build("VirtualNetworkStore")); 171 + .build());
155 172
156 /** 173 /**
157 * Distributed network store service activate method. 174 * Distributed network store service activate method.
...@@ -220,11 +237,25 @@ public class DistributedVirtualNetworkStore ...@@ -220,11 +237,25 @@ public class DistributedVirtualNetworkStore
220 237
221 networkIdVirtualPortSetConsistentMap = storageService.<NetworkId, Set<VirtualPort>>consistentMapBuilder() 238 networkIdVirtualPortSetConsistentMap = storageService.<NetworkId, Set<VirtualPort>>consistentMapBuilder()
222 .withSerializer(SERIALIZER) 239 .withSerializer(SERIALIZER)
223 - .withName("onos-networkId-virtualportss") 240 + .withName("onos-networkId-virtualports")
224 .withRelaxedReadConsistency() 241 .withRelaxedReadConsistency()
225 .build(); 242 .build();
226 networkIdVirtualPortSetMap = networkIdVirtualPortSetConsistentMap.asJavaMap(); 243 networkIdVirtualPortSetMap = networkIdVirtualPortSetConsistentMap.asJavaMap();
227 244
245 + intentKeyTunnelIdSetConsistentMap = storageService.<Key, Set<TunnelId>>consistentMapBuilder()
246 + .withSerializer(SERIALIZER)
247 + .withName("onos-intentKey-tunnelIds")
248 + .withRelaxedReadConsistency()
249 + .build();
250 + intentKeyTunnelIdSetMap = intentKeyTunnelIdSetConsistentMap.asJavaMap();
251 +
252 + intentKeyIntentDataConsistentMap = storageService.<Key, IntentData>consistentMapBuilder()
253 + .withSerializer(SERIALIZER)
254 + .withName("onos-intentKey-intentData")
255 + .withRelaxedReadConsistency()
256 + .build();
257 + intentKeyIntentDataMap = intentKeyIntentDataConsistentMap.asJavaMap();
258 +
228 log.info("Started"); 259 log.info("Started");
229 } 260 }
230 261
...@@ -607,6 +638,85 @@ public class DistributedVirtualNetworkStore ...@@ -607,6 +638,85 @@ public class DistributedVirtualNetworkStore
607 return ImmutableSet.copyOf(portSet); 638 return ImmutableSet.copyOf(portSet);
608 } 639 }
609 640
641 + @Override
642 + public synchronized void addOrUpdateIntent(Intent intent, IntentState state) {
643 + checkNotNull(intent, "Intent cannot be null");
644 + IntentData intentData = removeIntent(intent.key());
645 + if (intentData == null) {
646 + intentData = new IntentData(intent, state, new WallClockTimestamp(System.currentTimeMillis()));
647 + } else {
648 + intentData = new IntentData(intent, state, intentData.version());
649 + }
650 + intentKeyIntentDataMap.put(intent.key(), intentData);
651 + }
652 +
653 + @Override
654 + public IntentData removeIntent(Key intentKey) {
655 + checkNotNull(intentKey, "Intent key cannot be null");
656 + return intentKeyIntentDataMap.remove(intentKey);
657 + }
658 +
659 + @Override
660 + public void addTunnelId(Intent intent, TunnelId tunnelId) {
661 + // Add the tunnelId to the intent key set map
662 + Set<TunnelId> tunnelIdSet = intentKeyTunnelIdSetMap.remove(intent.key());
663 + if (tunnelIdSet == null) {
664 + tunnelIdSet = new HashSet<>();
665 + }
666 + tunnelIdSet.add(tunnelId);
667 + intentKeyTunnelIdSetMap.put(intent.key(), tunnelIdSet);
668 + }
669 +
670 + @Override
671 + public Set<TunnelId> getTunnelIds(Intent intent) {
672 + Set<TunnelId> tunnelIdSet = intentKeyTunnelIdSetMap.get(intent.key());
673 + return tunnelIdSet == null ? new HashSet<TunnelId>() : ImmutableSet.copyOf(tunnelIdSet);
674 + }
675 +
676 + @Override
677 + public void removeTunnelId(Intent intent, TunnelId tunnelId) {
678 + Set<TunnelId> tunnelIdSet = new HashSet<>();
679 + intentKeyTunnelIdSetMap.get(intent.key()).forEach(tunnelId1 -> {
680 + if (tunnelId1.equals(tunnelId)) {
681 + tunnelIdSet.add(tunnelId);
682 + }
683 + });
684 +
685 + if (!tunnelIdSet.isEmpty()) {
686 + intentKeyTunnelIdSetMap.compute(intent.key(), (key, existingTunnelIds) -> {
687 + if (existingTunnelIds == null || existingTunnelIds.isEmpty()) {
688 + return new HashSet<>();
689 + } else {
690 + return new HashSet<>(Sets.difference(existingTunnelIds, tunnelIdSet));
691 + }
692 + });
693 + }
694 + }
695 +
696 + @Override
697 + public Set<Intent> getIntents() {
698 + Set<Intent> intents = new HashSet<>();
699 + intentKeyIntentDataMap.values().forEach(intentData -> intents.add(intentData.intent()));
700 + return ImmutableSet.copyOf(intents);
701 + }
702 +
703 + @Override
704 + public Intent getIntent(Key key) {
705 + IntentData intentData = intentKeyIntentDataMap.get(key);
706 + return intentData == null ? null : intentData.intent();
707 + }
708 +
709 + @Override
710 + public Set<IntentData> getIntentData() {
711 + return ImmutableSet.copyOf(intentKeyIntentDataMap.values());
712 + }
713 +
714 + @Override
715 + public IntentData getIntentData(Key key) {
716 + IntentData intentData = intentKeyIntentDataMap.get(key);
717 + return intentData == null ? null : new IntentData(intentData);
718 + }
719 +
610 /** 720 /**
611 * Listener class to map listener set events to the virtual network events. 721 * Listener class to map listener set events to the virtual network events.
612 */ 722 */
......
...@@ -142,6 +142,12 @@ ...@@ -142,6 +142,12 @@
142 142
143 <dependency> 143 <dependency>
144 <groupId>org.onosproject</groupId> 144 <groupId>org.onosproject</groupId>
145 + <artifactId>onos-incubator-net</artifactId>
146 + <version>${project.version}</version>
147 + </dependency>
148 +
149 + <dependency>
150 + <groupId>org.onosproject</groupId>
145 <artifactId>onos-core-common</artifactId> 151 <artifactId>onos-core-common</artifactId>
146 <version>${project.version}</version> 152 <version>${project.version}</version>
147 </dependency> 153 </dependency>
......