2 * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
\r
4 * This program and the accompanying materials are made available under the
\r
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
\r
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
\r
9 package org.opendaylight.nemo.intent;
\r
11 import com.google.common.base.Optional;
\r
12 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
\r
13 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
\r
14 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
\r
15 import org.opendaylight.nemo.intent.computation.PNComputationUnit;
\r
16 import org.opendaylight.nemo.intent.computation.PNResourcesTracker;
\r
17 import org.opendaylight.nemo.intent.computation.VNComputationUnit;
\r
18 import org.opendaylight.nemo.intent.computation.VNMappingUnit;
\r
19 import org.opendaylight.nemo.intent.condition.ConditionManager;
\r
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.PhysicalNetwork;
\r
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.PhysicalPaths;
\r
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.paths.PhysicalPath;
\r
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.paths.PhysicalPathKey;
\r
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.VirtualNetworks;
\r
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.VirtualNetwork;
\r
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.VirtualNetworkBuilder;
\r
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.VirtualNetworkKey;
\r
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.*;
\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.arps.VirtualArp;
\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.links.VirtualLink;
\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.nodes.VirtualNode;
\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.paths.VirtualPath;
\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.routes.VirtualRoute;
\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.IntentVnMappingResults;
\r
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.VnPnMappingResults;
\r
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.UserIntentVnMapping;
\r
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.UserIntentVnMappingBuilder;
\r
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.UserIntentVnMappingKey;
\r
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.user.intent.vn.mapping.IntentVnMappingResult;
\r
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.vn.pn.mapping.results.UserVnPnMapping;
\r
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.vn.pn.mapping.results.UserVnPnMappingBuilder;
\r
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.vn.pn.mapping.results.UserVnPnMappingKey;
\r
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.vn.pn.mapping.results.user.vn.pn.mapping.VnPnMappingResult;
\r
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.NodeType;
\r
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;
\r
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.PhysicalPathId;
\r
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.VirtualNetworkId;
\r
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.Users;
\r
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Connection;
\r
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow;
\r
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Node;
\r
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.operations.Operation;
\r
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;
\r
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.UserKey;
\r
55 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
\r
56 import org.slf4j.Logger;
\r
57 import org.slf4j.LoggerFactory;
\r
59 import java.util.HashMap;
\r
60 import java.util.LinkedList;
\r
61 import java.util.List;
\r
62 import java.util.Map;
\r
63 import java.util.concurrent.ExecutionException;
\r
66 * Provide the user intent resolution APIs and distribute the user intents
\r
67 * to corresponding handling classes.
\r
69 * @author Zhigang Ji
\r
71 public class IntentResolver implements AutoCloseable {
\r
72 private static final Logger LOG = LoggerFactory.getLogger(IntentResolver.class);
\r
74 private final DataBroker dataBroker;
\r
77 * The node mapper to resolve the user's node intent.
\r
79 private NodeMapper nodeMapper;
\r
82 * The connection mapper to resolve the user's connection intent.
\r
84 private ConnectionMapper connectionMapper;
\r
87 * The flow manager to resolve the user's flow intent.
\r
89 private FlowManager flowManager;
\r
92 * The operation resolver to resolve the user's operation intent.
\r
94 private OperationResolver operationResolver;
\r
97 * The condition manager to resolve and manage the condition in the user's operation.
\r
99 private ConditionManager conditionManager;
\r
102 * The physical network computation unit.
\r
104 private PNComputationUnit pnComputationUnit;
\r
107 * The virtual network computation unit for all users.
\r
109 private Map<UserId, VNComputationUnit> vnComputationUnits;
\r
112 * Track the physical resource, re-resolve intent if related physical resource removed.
\r
114 private PNResourcesTracker pnResourcesTracker;
\r
117 * The virtual network mapping unit.
\r
119 private VNMappingUnit vnMappingUnit;
\r
121 public IntentResolver(DataBroker dataBroker) {
\r
124 this.dataBroker = dataBroker;
\r
126 nodeMapper = new NodeMapper(dataBroker);
\r
127 connectionMapper = new ConnectionMapper(dataBroker, nodeMapper);
\r
128 flowManager = new FlowManager(dataBroker);
\r
129 conditionManager = new ConditionManager(this);
\r
131 pnComputationUnit = new PNComputationUnit(dataBroker);
\r
132 vnComputationUnits = new HashMap<UserId, VNComputationUnit>();
\r
133 pnResourcesTracker = new PNResourcesTracker(dataBroker, this);
\r
134 vnMappingUnit = new VNMappingUnit(dataBroker, pnComputationUnit, pnResourcesTracker);
\r
136 operationResolver = new OperationResolver(dataBroker, conditionManager, vnComputationUnits);
\r
138 LOG.debug("Initialized the renderer common intent resolver.");
\r
144 * Resolve the user's intents to generate the virtual network, then map
\r
145 * the virtual network into the underlying physical network, finally, store
\r
146 * the generated intent mapping results into the data store, and various
\r
147 * renderers configure the underlying networks according to these results.
\r
149 * @param userId The user id for the intents to be resolved.
\r
151 public void resolveIntent(UserId userId) throws Exception {
\r
152 VNComputationUnit vnComputationUnit = vnComputationUnits.get(userId);
\r
154 VirtualNetworkId virtualNetworkId = new VirtualNetworkId(userId.getValue());
\r
155 VirtualNetworkKey virtualNetworkKey = new VirtualNetworkKey(virtualNetworkId);
\r
157 InstanceIdentifier<VirtualNetwork> virtualNetworkIid = InstanceIdentifier
\r
158 .builder(VirtualNetworks.class)
\r
159 .child(VirtualNetwork.class, virtualNetworkKey)
\r
161 InstanceIdentifier<UserIntentVnMapping> userIntentVnMappingIid = InstanceIdentifier
\r
162 .builder(IntentVnMappingResults.class)
\r
163 .child(UserIntentVnMapping.class, new UserIntentVnMappingKey(userId))
\r
165 InstanceIdentifier<UserVnPnMapping> userVnPnMappingIid = InstanceIdentifier
\r
166 .builder(VnPnMappingResults.class)
\r
167 .child(UserVnPnMapping.class, new UserVnPnMappingKey(virtualNetworkId))
\r
170 if ( null != vnComputationUnit ) {
\r
171 conditionManager.clear(userId);
\r
173 vnComputationUnit.close();
\r
174 vnComputationUnits.remove(userId);
\r
176 ReadWriteTransaction readWriteTransaction = dataBroker.newReadWriteTransaction();
\r
178 Optional<UserVnPnMapping> result;
\r
181 result = readWriteTransaction.read(LogicalDatastoreType.CONFIGURATION, userVnPnMappingIid).get();
\r
182 } catch ( InterruptedException exception ) {
\r
183 throw new IntentResolutionException("Can not read the vn-pn mapping results for the user " +
\r
184 userId.getValue() + ".");
\r
185 } catch ( ExecutionException exception ) {
\r
186 throw new IntentResolutionException("Can not read the vn-pn mapping results for the user " +
\r
187 userId.getValue() + ".");
\r
190 if ( result.isPresent() ) {
\r
191 UserVnPnMapping userVnPnMapping = result.get();
\r
192 List<VnPnMappingResult> vnPnMappingResults = userVnPnMapping.getVnPnMappingResult();
\r
193 InstanceIdentifier<PhysicalPath> physicalPathIid;
\r
194 PhysicalPathId physicalPathId;
\r
196 for ( VnPnMappingResult vnPnMappingResult : vnPnMappingResults ) {
\r
197 if ( VnPnMappingResult.VirtualResourceType.Vlink == vnPnMappingResult.getVirtualResourceType() ) {
\r
198 physicalPathId = new PhysicalPathId(vnPnMappingResult.getPhysicalResourceEntityId().getValue());
\r
199 physicalPathIid = InstanceIdentifier.builder(PhysicalNetwork.class)
\r
200 .child(PhysicalPaths.class)
\r
201 .child(PhysicalPath.class, new PhysicalPathKey(physicalPathId))
\r
204 readWriteTransaction.delete(LogicalDatastoreType.OPERATIONAL, physicalPathIid);
\r
209 // readWriteTransaction.delete(LogicalDatastoreType.CONFIGURATION, virtualNetworkIid);
\r
210 // readWriteTransaction.delete(LogicalDatastoreType.CONFIGURATION, userIntentVnMappingIid);
\r
211 // readWriteTransaction.delete(LogicalDatastoreType.CONFIGURATION, userVnPnMappingIid);
\r
212 // TODO: åˆ é™¤intent processing status
\r
214 readWriteTransaction.submit();
\r
217 ReadWriteTransaction readWriteTransaction = dataBroker.newReadWriteTransaction();
\r
219 InstanceIdentifier<User> userIid = InstanceIdentifier.builder(Users.class)
\r
220 .child(User.class, new UserKey(userId))
\r
222 Optional<User> result;
\r
225 result = readWriteTransaction.read(LogicalDatastoreType.CONFIGURATION, userIid).get();
\r
226 } catch ( InterruptedException exception ) {
\r
227 throw new IntentResolutionException("Can not read the data of the user " +
\r
228 userId.getValue() + ".");
\r
229 } catch ( ExecutionException exception ) {
\r
230 throw new IntentResolutionException("Can not read the data of the user " +
\r
231 userId.getValue() + ".");
\r
234 if ( !result.isPresent() ) {
\r
235 throw new IntentResolutionException("The data of the user " +
\r
236 userId.getValue() + " does not exist.");
\r
239 User user = result.get();
\r
241 if ( null != user.getObjects() ) {
\r
242 VirtualNodes virtualNodes = new VirtualNodesBuilder()
\r
243 .setVirtualNode(new LinkedList<VirtualNode>())
\r
245 VirtualLinks virtualLinks = new VirtualLinksBuilder()
\r
246 .setVirtualLink(new LinkedList<VirtualLink>())
\r
248 VirtualPaths virtualPaths = new VirtualPathsBuilder()
\r
249 .setVirtualPath(new LinkedList<VirtualPath>())
\r
251 VirtualRoutes virtualRoutes = new VirtualRoutesBuilder()
\r
252 .setVirtualRoute(new LinkedList<VirtualRoute>())
\r
254 VirtualArps virtualArps = new VirtualArpsBuilder()
\r
255 .setVirtualArp(new LinkedList<VirtualArp>())
\r
257 VirtualNetwork virtualNetwork = new VirtualNetworkBuilder()
\r
258 .setNetworkId(virtualNetworkId)
\r
260 .setVirtualNodes(virtualNodes)
\r
261 .setVirtualLinks(virtualLinks)
\r
262 .setVirtualPaths(virtualPaths)
\r
263 .setVirtualRoutes(virtualRoutes)
\r
264 .setVirtualArps(virtualArps)
\r
267 UserIntentVnMapping userIntentVnMapping = new UserIntentVnMappingBuilder()
\r
269 .setVirtualNetworkId(virtualNetworkId)
\r
270 .setIntentVnMappingResult(new LinkedList<IntentVnMappingResult>())
\r
273 UserVnPnMapping userVnPnMapping = new UserVnPnMappingBuilder()
\r
274 .setVirtualNetworkId(virtualNetworkId)
\r
276 .setVnPnMappingResult(new LinkedList<VnPnMappingResult>())
\r
279 List<PhysicalPath> physicalPaths = new LinkedList<PhysicalPath>();
\r
281 List<Node> nodes = user.getObjects().getNode();
\r
282 List<Node> hosts = new LinkedList<Node>();
\r
283 List<Node> layer2Groups = new LinkedList<Node>();
\r
284 List<Node> layer3Groups = new LinkedList<Node>();
\r
285 List<Node> externalLayer3Groups = new LinkedList<Node>();
\r
286 List<Node> serviceChainGroups = new LinkedList<Node>();
\r
287 List<Node> serviceFunctions = new LinkedList<Node>();
\r
289 NodeType hostNodeType = new NodeType("host");
\r
290 NodeType layer2GroupNodeType = new NodeType("l2-group");
\r
291 NodeType layer3GroupNodeType = new NodeType("l3-group");
\r
292 NodeType externalGroupNodeType = new NodeType("ext-group");
\r
293 NodeType serviceChainGroupNodeType = new NodeType("chain-group");
\r
294 NodeType firewallNodeType = new NodeType("fw");
\r
295 NodeType loadbalancerNodeType = new NodeType("lb");
\r
296 NodeType cacheNodeType = new NodeType("cache");
\r
299 if ( null != nodes ) {
\r
300 for ( Node node : nodes ) {
\r
301 nodeType = node.getNodeType();
\r
303 if ( nodeType.equals(hostNodeType) ) {
\r
307 if ( nodeType.equals(layer2GroupNodeType) ) {
\r
308 layer2Groups.add(node);
\r
311 if ( nodeType.equals(layer3GroupNodeType) ) {
\r
312 layer3Groups.add(node);
\r
315 if ( nodeType.equals(externalGroupNodeType) ) {
\r
316 if ( IntentResolverUtils.checkExternalLayer3Group(node) ) {
\r
317 externalLayer3Groups.add(node);
\r
321 if ( nodeType.equals(serviceChainGroupNodeType) ) {
\r
322 serviceChainGroups.add(node);
\r
325 if ( nodeType.equals(firewallNodeType)
\r
326 || nodeType.equals(loadbalancerNodeType)
\r
327 || nodeType.equals(cacheNodeType) ) {
\r
328 serviceFunctions.add(node);
\r
332 for ( Node node : hosts ) {
\r
333 nodeMapper.resolveHost(user, node, virtualNetwork, userIntentVnMapping);
\r
336 for ( Node node : layer2Groups ) {
\r
337 nodeMapper.resolveLayer2Group(user, node, virtualNetwork, userIntentVnMapping);
\r
340 for ( Node node : externalLayer3Groups ) {
\r
341 nodeMapper.resolveExternalLayer3Group(user, node, virtualNetwork, userIntentVnMapping);
\r
344 for ( Node node : layer3Groups ) {
\r
345 nodeMapper.resolveLayer3Group(user, node, virtualNetwork, userIntentVnMapping);
\r
348 for ( Node node : serviceFunctions ) {
\r
349 nodeMapper.resolveServiceFunction(user, node, virtualNetwork, userIntentVnMapping);
\r
352 for ( Node node : serviceChainGroups ) {
\r
353 nodeMapper.resolveServiceChainGroup(user, node, virtualNetwork, userIntentVnMapping);
\r
357 List<Connection> connections = user.getObjects().getConnection();
\r
359 if ( null != connections ) {
\r
360 for ( Connection connection : connections ) {
\r
361 connectionMapper.resolveConnection(user, connection, virtualNetwork, userIntentVnMapping);
\r
365 List<Flow> flows = user.getObjects().getFlow();
\r
367 if ( null != flows ) {
\r
368 for ( Flow flow : flows ) {
\r
369 flowManager.resolveFlow(userId, flow);
\r
373 List<Operation> operationsApplyingToNode = new LinkedList<Operation>();
\r
374 List<Operation> operationsApplyingToConnection = new LinkedList<Operation>();
\r
375 List<Operation> operationsApplyingToFlow = new LinkedList<Operation>();
\r
377 if ( null != user.getOperations() ) {
\r
378 List<Operation> operations = user.getOperations().getOperation();
\r
380 if ( null != operations ) {
\r
381 operationResolver.classifyOperations(user, operations, operationsApplyingToNode,
\r
382 operationsApplyingToConnection, operationsApplyingToFlow);
\r
386 if ( !operationsApplyingToNode.isEmpty() ) {
\r
387 for ( Operation operation : operationsApplyingToNode ) {
\r
388 operationResolver.resolveOperation(user, operation, virtualNetwork, userIntentVnMapping);
\r
392 if ( !operationsApplyingToConnection.isEmpty() ) {
\r
393 for ( Operation operation : operationsApplyingToConnection ) {
\r
394 operationResolver.resolveOperation(user, operation, virtualNetwork, userIntentVnMapping);
\r
398 IntentResolverUtils.copyPhysicalNetworkConfigToOperational(dataBroker);
\r
400 vnMappingUnit.virtualNetworkMapping(virtualNetwork, userVnPnMapping, physicalPaths);
\r
401 vnComputationUnit = new VNComputationUnit(dataBroker, virtualNetwork);
\r
402 vnComputationUnits.put(userId, vnComputationUnit);
\r
404 int currentVirtualLinkNum = virtualLinks.getVirtualLink().size();
\r
406 if ( !operationsApplyingToFlow.isEmpty() ) {
\r
407 for ( Operation operation : operationsApplyingToFlow ) {
\r
408 operationResolver.resolveOperation(user, operation, virtualNetwork, userIntentVnMapping);
\r
412 List<VirtualLink> virtualLinkList = virtualLinks.getVirtualLink();
\r
413 List<VirtualLink> unmappedVirtualLinkList =
\r
414 virtualLinkList.subList(currentVirtualLinkNum, virtualLinkList.size());
\r
416 vnMappingUnit.virtualNetworkMapping(virtualNetwork,
\r
417 unmappedVirtualLinkList, userVnPnMapping, physicalPaths);
\r
419 LOG.debug("{}", virtualNetwork);
\r
420 LOG.debug("{}", userIntentVnMapping);
\r
421 LOG.debug("{}", userVnPnMapping);
\r
422 LOG.debug("{}", physicalPaths);
\r
424 readWriteTransaction.put(LogicalDatastoreType.CONFIGURATION, virtualNetworkIid, virtualNetwork, true);
\r
425 readWriteTransaction.put(LogicalDatastoreType.CONFIGURATION, userIntentVnMappingIid, userIntentVnMapping, true);
\r
426 readWriteTransaction.put(LogicalDatastoreType.CONFIGURATION, userVnPnMappingIid, userVnPnMapping, true);
\r
428 InstanceIdentifier<PhysicalPath> physicalPathIid;
\r
430 for ( PhysicalPath physicalPath : physicalPaths ) {
\r
431 physicalPathIid = InstanceIdentifier.builder(PhysicalNetwork.class)
\r
432 .child(PhysicalPaths.class)
\r
433 .child(PhysicalPath.class, new PhysicalPathKey(physicalPath.getPathId()))
\r
436 readWriteTransaction.put(LogicalDatastoreType.OPERATIONAL, physicalPathIid, physicalPath, true);
\r
439 readWriteTransaction.submit();
\r
446 public void close() throws Exception {
\r
447 if ( null != pnComputationUnit ) {
\r
448 pnComputationUnit.close();
\r
451 for ( VNComputationUnit vnComputationUnit : vnComputationUnits.values() ) {
\r
452 if ( null != vnComputationUnit ) {
\r
453 vnComputationUnit.close();
\r
457 if ( null != pnResourcesTracker ) {
\r
458 pnResourcesTracker.close();
\r
461 if ( null != vnMappingUnit ) {
\r
462 vnMappingUnit.close();
\r