blob: 753b2e3b0d7be14627393876fd934df775f1f1ea [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/**
Brian Stankefb61df42016-07-25 11:47:51 -040049 * Intent service implementation built on the virtual network service.
Brian Stanke11f6d532016-07-05 16:17:59 -040050 */
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.
Brian Stankefb61df42016-07-25 11:47:51 -0400151 store.getTunnelIds(intent).forEach(tunnelId -> {
152 Key intentKey = Key.of(tunnelId.id(), intent.appId());
153 Intent physicalIntent = intentService.getIntent(intentKey);
154 checkNotNull(physicalIntent, INTENT_NULL);
Brian Stanke11f6d532016-07-05 16:17:59 -0400155
Brian Stankefb61df42016-07-25 11:47:51 -0400156 // Withdraw the physical intent(s)
157 log.debug("Withdrawing pt-pt intent: " + physicalIntent);
158 intentService.withdraw(physicalIntent);
159 });
Brian Stanke11f6d532016-07-05 16:17:59 -0400160 // Now withdraw the virtual intent
Brian Stankefb61df42016-07-25 11:47:51 -0400161 log.debug("Withdrawing virtual intent: " + intent);
Brian Stanke11f6d532016-07-05 16:17:59 -0400162 intentService.withdraw(intent);
163 }
164
165 @Override
166 public void purge(Intent intent) {
167 checkNotNull(intent, INTENT_NULL);
168 // Purges the physical intents created for each tunnelId.
169 store.getTunnelIds(intent)
170 .forEach(tunnelId -> {
171 Key intentKey = Key.of(tunnelId.id(), intent.appId());
172 Intent physicalIntent = intentService.getIntent(intentKey);
173 checkNotNull(physicalIntent, INTENT_NULL);
174
175 // Purge the physical intent(s)
176 intentService.purge(physicalIntent);
177 store.removeTunnelId(intent, tunnelId);
178 });
179 // Now purge the virtual intent
180 intentService.purge(intent);
181 }
182
183 @Override
184 public Intent getIntent(Key key) {
185 checkNotNull(key, KEY_NULL);
186 return store.getIntent(key);
187 }
188
189 @Override
190 public Iterable<Intent> getIntents() {
191 return store.getIntents();
192 }
193
194 @Override
195 public Iterable<IntentData> getIntentData() {
196 return store.getIntentData();
197 }
198
199 @Override
200 public long getIntentCount() {
201 return Iterators.size(getIntents().iterator());
202 }
203
204 @Override
205 public IntentState getIntentState(Key intentKey) {
206 checkNotNull(intentKey, KEY_NULL);
Yuta HIGUCHIe2eeae82016-07-28 13:56:31 -0700207 return Optional.ofNullable(store.getIntentData(intentKey))
208 .map(IntentData::state)
209 .orElse(null);
Brian Stanke11f6d532016-07-05 16:17:59 -0400210 }
211
212 @Override
213 public List<Intent> getInstallableIntents(Key intentKey) {
214 List<Intent> intents = new ArrayList<>();
215 getIntentData().forEach(intentData -> {
216 if (intentData.intent().key().equals(intentKey)) {
217 intents.addAll(intentData.installables());
218 }
219 });
220 return intents;
221 }
222
223 @Override
224 public boolean isLocal(Key intentKey) {
225 checkNotNull(intentKey, INTENT_KEY_NULL);
226 Intent intent = getIntent(intentKey);
227 checkNotNull(intent, INTENT_NULL);
228 return partitionService.isMine(intentKey);
229 }
230
231 @Override
232 public Iterable<Intent> getPending() {
233 return null;
234 }
235
236
237 @Override
238 public VirtualNetwork network() {
239 return network;
240 }
241}