blob: 191bec2d0364100748411a345b4be20b8d79cb44 [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;
27import org.onosproject.net.ConnectPoint;
28import org.onosproject.net.DeviceId;
29import org.onosproject.net.Port;
30import org.onosproject.net.PortNumber;
31import org.onosproject.net.intent.Intent;
32import org.onosproject.net.intent.IntentData;
33import org.onosproject.net.intent.IntentEvent;
34import org.onosproject.net.intent.IntentListener;
35import org.onosproject.net.intent.IntentPartitionService;
36import org.onosproject.net.intent.IntentService;
37import org.onosproject.net.intent.IntentState;
38import org.onosproject.net.intent.Key;
39import org.slf4j.Logger;
40import org.slf4j.LoggerFactory;
41
42import java.util.ArrayList;
43import java.util.List;
44import java.util.Optional;
45
46import static com.google.common.base.Preconditions.*;
47
48/**
49 * intent service implementation built on the virtual network service.
50 */
51public 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}