blob: 7b00e1dbb927f681f49ac7a6ad2cf52f8170e7b5 [file] [log] [blame]
Brian Stanke11f6d532016-07-05 16:17:59 -04001/*
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
17package org.onosproject.incubator.net.virtual.impl;
18
19import com.google.common.collect.Iterators;
20import org.onlab.osgi.ServiceDirectory;
21import org.onosproject.event.AbstractListenerManager;
22import org.onosproject.incubator.net.virtual.VirtualNetwork;
23import org.onosproject.incubator.net.virtual.VirtualNetworkIntent;
24import org.onosproject.incubator.net.virtual.VirtualNetworkService;
25import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
26import org.onosproject.incubator.net.virtual.VirtualPort;
yoonseon214963b2016-11-21 15:41:07 -080027import org.onosproject.incubator.net.virtual.VnetService;
Brian Stanke11f6d532016-07-05 16:17:59 -040028import org.onosproject.net.ConnectPoint;
29import org.onosproject.net.DeviceId;
30import org.onosproject.net.Port;
31import org.onosproject.net.PortNumber;
32import org.onosproject.net.intent.Intent;
33import org.onosproject.net.intent.IntentData;
34import org.onosproject.net.intent.IntentEvent;
35import org.onosproject.net.intent.IntentListener;
Madan Jampani3b8101a2016-09-15 13:22:01 -070036import org.onosproject.net.intent.WorkPartitionService;
Brian Stanke11f6d532016-07-05 16:17:59 -040037import org.onosproject.net.intent.IntentService;
38import org.onosproject.net.intent.IntentState;
39import org.onosproject.net.intent.Key;
40import org.slf4j.Logger;
41import org.slf4j.LoggerFactory;
42
43import java.util.ArrayList;
44import java.util.List;
45import java.util.Optional;
46
47import static com.google.common.base.Preconditions.*;
48
49/**
Brian Stankefb61df42016-07-25 11:47:51 -040050 * Intent service implementation built on the virtual network service.
Brian Stanke11f6d532016-07-05 16:17:59 -040051 */
yoonseon214963b2016-11-21 15:41:07 -080052public class VirtualNetworkIntentManager
53 extends AbstractListenerManager<IntentEvent, IntentListener>
Brian Stanke11f6d532016-07-05 16:17:59 -040054 implements IntentService, VnetService {
55
56 private final Logger log = LoggerFactory.getLogger(getClass());
57
58 private static final String NETWORK_NULL = "Network cannot be null";
59 private static final String NETWORK_ID_NULL = "Network ID cannot be null";
60 private static final String DEVICE_NULL = "Device cannot be null";
61 private static final String INTENT_NULL = "Intent cannot be null";
62 private static final String KEY_NULL = "Key cannot be null";
63 private static final String APP_ID_NULL = "Intent app identifier cannot be null";
64 private static final String INTENT_KEY_NULL = "Intent key cannot be null";
65 private static final String CP_NULL = "Connect Point cannot be null";
66
67 protected IntentService intentService;
68 protected VirtualNetworkStore store;
Madan Jampani3b8101a2016-09-15 13:22:01 -070069 protected WorkPartitionService partitionService;
Brian Stanke11f6d532016-07-05 16:17:59 -040070
71 private final VirtualNetwork network;
72 private final VirtualNetworkService manager;
73
74 /**
75 * Creates a new VirtualNetworkIntentService object.
76 *
77 * @param virtualNetworkManager virtual network manager service
78 * @param network virtual network
79 * @param serviceDirectory service directory
80 */
yoonseon214963b2016-11-21 15:41:07 -080081 public VirtualNetworkIntentManager(VirtualNetworkService virtualNetworkManager,
82 VirtualNetwork network,
Brian Stanke11f6d532016-07-05 16:17:59 -040083 ServiceDirectory serviceDirectory) {
84 checkNotNull(network, NETWORK_NULL);
85 this.network = network;
86 this.manager = virtualNetworkManager;
87 this.store = serviceDirectory.get(VirtualNetworkStore.class);
88 this.intentService = serviceDirectory.get(IntentService.class);
Madan Jampani3b8101a2016-09-15 13:22:01 -070089 this.partitionService = serviceDirectory.get(WorkPartitionService.class);
Brian Stanke11f6d532016-07-05 16:17:59 -040090 }
91
92 @Override
93 public void submit(Intent intent) {
94 checkNotNull(intent, INTENT_NULL);
95 checkState(intent instanceof VirtualNetworkIntent, "Only VirtualNetworkIntent is supported.");
96 checkArgument(validateIntent((VirtualNetworkIntent) intent), "Invalid Intent");
97
98 intentService.submit(intent);
99 }
100
101 /**
102 * Returns true if the virtual network intent is valid.
103 *
104 * @param intent virtual network intent
105 * @return true if intent is valid
106 */
107 private boolean validateIntent(VirtualNetworkIntent intent) {
108 checkNotNull(intent, INTENT_NULL);
109 checkNotNull(intent.networkId(), NETWORK_ID_NULL);
110 checkNotNull(intent.appId(), APP_ID_NULL);
111 checkNotNull(intent.key(), INTENT_KEY_NULL);
112 ConnectPoint ingressPoint = intent.ingressPoint();
113 ConnectPoint egressPoint = intent.egressPoint();
114
115 return (validateConnectPoint(ingressPoint) && validateConnectPoint(egressPoint));
116 }
117
118 /**
119 * Returns true if the connect point is valid.
120 *
121 * @param connectPoint connect point
122 * @return true if connect point is valid
123 */
124 private boolean validateConnectPoint(ConnectPoint connectPoint) {
125 checkNotNull(connectPoint, CP_NULL);
126 Port port = getPort(connectPoint.deviceId(), connectPoint.port());
127 return port == null ? false : true;
128 }
129
130 /**
131 * Returns the virtual port for the given device identifier and port number.
132 *
133 * @param deviceId virtual device identifier
134 * @param portNumber virtual port number
135 * @return virtual port
136 */
137 private Port getPort(DeviceId deviceId, PortNumber portNumber) {
138 checkNotNull(deviceId, DEVICE_NULL);
139
140 Optional<VirtualPort> foundPort = manager.getVirtualPorts(this.network.id(), deviceId)
141 .stream()
142 .filter(port -> port.number().equals(portNumber))
143 .findFirst();
144 if (foundPort.isPresent()) {
145 return foundPort.get();
146 }
147 return null;
148 }
149
150 @Override
151 public void withdraw(Intent intent) {
152 checkNotNull(intent, INTENT_NULL);
153 // Withdraws the physical intents created due to the virtual intents.
Brian Stankefb61df42016-07-25 11:47:51 -0400154 store.getTunnelIds(intent).forEach(tunnelId -> {
155 Key intentKey = Key.of(tunnelId.id(), intent.appId());
156 Intent physicalIntent = intentService.getIntent(intentKey);
157 checkNotNull(physicalIntent, INTENT_NULL);
Brian Stanke11f6d532016-07-05 16:17:59 -0400158
Brian Stankefb61df42016-07-25 11:47:51 -0400159 // Withdraw the physical intent(s)
160 log.debug("Withdrawing pt-pt intent: " + physicalIntent);
161 intentService.withdraw(physicalIntent);
162 });
Brian Stanke11f6d532016-07-05 16:17:59 -0400163 // Now withdraw the virtual intent
Brian Stankefb61df42016-07-25 11:47:51 -0400164 log.debug("Withdrawing virtual intent: " + intent);
Brian Stanke11f6d532016-07-05 16:17:59 -0400165 intentService.withdraw(intent);
166 }
167
168 @Override
169 public void purge(Intent intent) {
170 checkNotNull(intent, INTENT_NULL);
171 // Purges the physical intents created for each tunnelId.
172 store.getTunnelIds(intent)
173 .forEach(tunnelId -> {
174 Key intentKey = Key.of(tunnelId.id(), intent.appId());
175 Intent physicalIntent = intentService.getIntent(intentKey);
176 checkNotNull(physicalIntent, INTENT_NULL);
177
178 // Purge the physical intent(s)
179 intentService.purge(physicalIntent);
180 store.removeTunnelId(intent, tunnelId);
181 });
182 // Now purge the virtual intent
183 intentService.purge(intent);
184 }
185
186 @Override
187 public Intent getIntent(Key key) {
188 checkNotNull(key, KEY_NULL);
189 return store.getIntent(key);
190 }
191
192 @Override
193 public Iterable<Intent> getIntents() {
194 return store.getIntents();
195 }
196
197 @Override
Brian O'Connor38224302016-08-02 22:03:01 -0700198 public void addPending(IntentData intentData) {
199 intentService.addPending(intentData);
200 }
201
202 @Override
Brian Stanke11f6d532016-07-05 16:17:59 -0400203 public Iterable<IntentData> getIntentData() {
204 return store.getIntentData();
205 }
206
207 @Override
208 public long getIntentCount() {
209 return Iterators.size(getIntents().iterator());
210 }
211
212 @Override
213 public IntentState getIntentState(Key intentKey) {
214 checkNotNull(intentKey, KEY_NULL);
Yuta HIGUCHIe2eeae82016-07-28 13:56:31 -0700215 return Optional.ofNullable(store.getIntentData(intentKey))
216 .map(IntentData::state)
217 .orElse(null);
Brian Stanke11f6d532016-07-05 16:17:59 -0400218 }
219
220 @Override
221 public List<Intent> getInstallableIntents(Key intentKey) {
222 List<Intent> intents = new ArrayList<>();
223 getIntentData().forEach(intentData -> {
224 if (intentData.intent().key().equals(intentKey)) {
225 intents.addAll(intentData.installables());
226 }
227 });
228 return intents;
229 }
230
231 @Override
232 public boolean isLocal(Key intentKey) {
233 checkNotNull(intentKey, INTENT_KEY_NULL);
234 Intent intent = getIntent(intentKey);
235 checkNotNull(intent, INTENT_NULL);
Madan Jampani3b8101a2016-09-15 13:22:01 -0700236 return partitionService.isMine(intentKey, Key::hash);
Brian Stanke11f6d532016-07-05 16:17:59 -0400237 }
238
239 @Override
240 public Iterable<Intent> getPending() {
241 return null;
242 }
243
244
245 @Override
246 public VirtualNetwork network() {
247 return network;
248 }
249}