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 org.opendaylight.controller.md.sal.binding.api.DataBroker;
\r
12 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.VirtualNetwork;
\r
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.links.VirtualLink;
\r
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.links.VirtualLinkBuilder;
\r
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.nodes.VirtualNode;
\r
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.paths.VirtualPath;
\r
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.paths.VirtualPathBuilder;
\r
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.VirtualPort;
\r
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.node.instance.VirtualPortBuilder;
\r
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.UserIntentVnMapping;
\r
21 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
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.user.intent.vn.mapping.IntentVnMappingResultBuilder;
\r
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.user.intent.vn.mapping.intent.vn.mapping.result.VirtualResource;
\r
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.user.intent.vn.mapping.intent.vn.mapping.result.VirtualResourceBuilder;
\r
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.ActionName;
\r
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.IntentId;
\r
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.NodeId;
\r
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.NodeType;
\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.*;
\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Connection;
\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow;
\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Node;
\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.operations.Operation;
\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;
\r
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.action.instance.parameter.values.StringValue;
\r
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.condition.instance.ConditionSegment;
\r
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.operation.instance.Action;
\r
38 import org.opendaylight.yangtools.yang.binding.DataObject;
\r
39 import org.slf4j.Logger;
\r
40 import org.slf4j.LoggerFactory;
\r
42 import java.util.ArrayList;
\r
43 import java.util.LinkedList;
\r
44 import java.util.List;
\r
45 import java.util.UUID;
\r
48 * Resolve the user's operation intent that might act on the node, connection
\r
49 * or flow. Perform the monitoring if the operation contains a condition which
\r
50 * determines when to execute the operation. Resolve the actions included in
\r
51 * the operation and decide how to implement them on the physical network.
\r
53 * @author Zhigang Ji
\r
55 public class OperationResolver {
\r
56 private static final Logger LOG = LoggerFactory.getLogger(OperationResolver.class);
\r
58 private final DataBroker dataBroker;
\r
61 * The action resolver to resolve actions in the operation.
\r
63 private ActionResolver actionResolver;
\r
65 public OperationResolver(DataBroker dataBroker) {
\r
68 this.dataBroker = dataBroker;
\r
70 actionResolver = new ActionResolver();
\r
72 LOG.debug("Initialized the renderer common operation resolver.");
\r
78 * Resolve the user's operation intent and perform the monitoring for
\r
79 * the condition that it contains. Generate the intent mapping results
\r
80 * for the operation in the data store, which denote how to implement
\r
81 * it on the physical network.
\r
83 * @param user The user for the operation.
\r
84 * @param operation The operation to be resolved.
\r
85 * @param virtualNetwork The virtual network for the user.
\r
86 * @param userIntentVnMapping The intent-vn mapping for the user.
\r
88 protected void resolveOperation(User user, Operation operation, VirtualNetwork virtualNetwork,
\r
89 UserIntentVnMapping userIntentVnMapping)
\r
90 throws IntentResolutionException {
\r
91 DataObject dataObject = IntentResolverUtils
\r
92 .getObject(user.getObjects(), operation.getTargetObject());
\r
94 if ( null == dataObject ) {
\r
95 throw new IntentResolutionException("The target object of the operation " +
\r
96 operation.getOperationId().getValue() + " does not exist.");
\r
99 List<Operation> operations = user.getOperations().getOperation();
\r
100 List<Operation> sameTargetObjectOperations = IntentResolverUtils
\r
101 .getSameTargetObjectOperations(operations, operation);
\r
103 if ( !sameTargetObjectOperations.isEmpty() ) {
\r
104 List<Operation> greaterPriorityOperations = new LinkedList<Operation>();
\r
105 List<Operation> equalPriorityOperations = new LinkedList<Operation>();
\r
107 IntentResolverUtils.getGreaterAndEqualPriorityOperations(sameTargetObjectOperations,
\r
108 operation, greaterPriorityOperations, equalPriorityOperations);
\r
110 if ( greaterPriorityOperations.isEmpty() ) {
\r
111 if ( !equalPriorityOperations.isEmpty() ) {
\r
112 Operation conflictingOperation = IntentResolverUtils
\r
113 .getConflictingOperation(equalPriorityOperations, operation);
\r
115 if ( null != conflictingOperation ) {
\r
116 throw new IntentResolutionException("The operation " +
\r
117 operation.getOperationId().getValue() + " conflicts with the one " +
\r
118 conflictingOperation.getOperationId().getValue() + ".");
\r
126 List<ConditionSegment> conditionSegments = operation.getConditionSegment();
\r
128 if ( null != conditionSegments && !conditionSegments.isEmpty() ) {
\r
134 List<Action> actions = operation.getAction();
\r
136 if ( null != actions && !actions.isEmpty() ) {
\r
137 if ( dataObject instanceof Node ) {
\r
138 actionResolver.resolveActions(user, operation, (Node)dataObject,
\r
139 virtualNetwork, userIntentVnMapping);
\r
140 } else if ( dataObject instanceof Connection ) {
\r
141 actionResolver.resolveActions(user, operation, (Connection)dataObject,
\r
142 virtualNetwork, userIntentVnMapping);
\r
144 actionResolver.resolveActions(user, operation, (Flow)dataObject,
\r
145 virtualNetwork, userIntentVnMapping);
\r
153 * Perform the monitoring for the operation that contains a condition
\r
154 * which determines when to execute the operation.
\r
156 * @author Zhigang Ji
\r
158 private class ConditionMonitor {
\r
163 * Resolve the actions included in the operation and decide how to
\r
164 * implement them on the physical network.
\r
166 * @author Zhigang Ji
\r
168 private class ActionResolver {
\r
173 * @param operation TODO
\r
175 * @param virtualNetwork TODO
\r
176 * @param userIntentVnMapping TODO
\r
178 protected void resolveActions(User user, Operation operation, Node node,
\r
179 VirtualNetwork virtualNetwork,
\r
180 UserIntentVnMapping userIntentVnMapping)
\r
181 throws IntentResolutionException {
\r
191 * @param operation TODO
\r
192 * @param connection TODO
\r
193 * @param virtualNetwork TODO
\r
194 * @param userIntentVnMapping TODO
\r
196 protected void resolveActions(User user, Operation operation, Connection connection,
\r
197 VirtualNetwork virtualNetwork,
\r
198 UserIntentVnMapping userIntentVnMapping)
\r
199 throws IntentResolutionException {
\r
209 * @param operation TODO
\r
211 * @param virtualNetwork TODO
\r
212 * @param userIntentVnMapping TODO
\r
214 protected void resolveActions(User user, Operation operation, Flow flow,
\r
215 VirtualNetwork virtualNetwork,
\r
216 UserIntentVnMapping userIntentVnMapping)
\r
217 throws IntentResolutionException {
\r
218 List<Action> actions = operation.getAction();
\r
220 ActionName actionName = new ActionName("go-through");
\r
221 Action goThroughAction = IntentResolverUtils.getAction(actions, actionName);
\r
223 if ( null != goThroughAction ) {
\r
224 resolveGoThroughAction(user, operation, flow, goThroughAction,
\r
225 virtualNetwork, userIntentVnMapping);
\r
230 throw new IntentResolutionException("Unsupported action combination.");
\r
240 * @param operation TODO
\r
242 * @param goThroughAction TODO
\r
243 * @param virtualNetwork TODO
\r
244 * @param userIntentVnMapping TODO
\r
246 private void resolveGoThroughAction(User user, Operation operation, Flow flow,
\r
247 Action goThroughAction,
\r
248 VirtualNetwork virtualNetwork,
\r
249 UserIntentVnMapping userIntentVnMapping)
\r
250 throws IntentResolutionException {
\r
251 List<StringValue> parameterValues = goThroughAction.getParameterValues().getStringValue();
\r
253 if ( !parameterValues.isEmpty() ) {
\r
254 List<Node> nodes = user.getObjects().getNode();
\r
256 if ( null == nodes || nodes.isEmpty() ) {
\r
257 throw new IntentResolutionException("The nodes specified by the action parameters " +
\r
258 "of the operation " + operation.getOperationId().getValue() + " does not exist.");
\r
261 NodeId nodeId = new NodeId(parameterValues.get(0).getValue());
\r
262 Node node = IntentResolverUtils.getNode(nodes, nodeId);
\r
264 if ( null == node ) {
\r
265 throw new IntentResolutionException("The node " + nodeId.getValue() + " specified by the" +
\r
266 " action parameter of the operation " + operation.getOperationId().getValue() +
\r
267 " does not exist.");
\r
270 List<VirtualNode> virtualNodes = virtualNetwork.getVirtualNodes().getVirtualNode();
\r
271 List<VirtualLink> virtualLinks = virtualNetwork.getVirtualLinks().getVirtualLink();
\r
272 List<VirtualPath> virtualPaths = virtualNetwork.getVirtualPaths().getVirtualPath();
\r
273 List<IntentVnMappingResult> intentVnMappingResults = userIntentVnMapping.getIntentVnMappingResult();
\r
274 List<VirtualResource> virtualResources = null;
\r
276 if ( node.getNodeType().equals(new NodeType("chain-group")) ) {
\r
277 if ( IntentResolverUtils.checkAllLayer2OperatingMode(node.getSubNode(), nodes) ) {
\r
279 } else if ( IntentResolverUtils.checkAllLayer3OperatingMode(node.getSubNode(), nodes) ) {
\r
280 IntentVnMappingResult intentVnMappingResult = IntentResolverUtils.getIntentVnMappingResult(
\r
281 intentVnMappingResults, new IntentId(node.getNodeId().getValue()));
\r
283 if ( null == intentVnMappingResult ) {
\r
284 throw new IntentResolutionException("Can not get the intent-vn mapping result " +
\r
285 "for the node " + node.getNodeId().getValue() + ".");
\r
288 VirtualNode sourceVirtualNode = IntentResolverUtils.getSourceVirtualRouterOfFlow(
\r
289 virtualNodes, flow, nodes, intentVnMappingResults);
\r
291 if ( null == sourceVirtualNode ) {
\r
292 throw new IntentResolutionException("Can not get the source virtual node " +
\r
293 "of the flow " + flow.getFlowId().getValue() + ".");
\r
296 VirtualNode destinationVirtualNode = IntentResolverUtils.getDestinationVirtualRouterOfFlow(
\r
297 virtualNodes, flow, nodes, intentVnMappingResults);
\r
299 if ( null == destinationVirtualNode ) {
\r
300 throw new IntentResolutionException("Can not get the destination virtual node " +
\r
301 "of the flow " + flow.getFlowId().getValue() + ".");
\r
304 List<VirtualResource> virtualResources1 = IntentResolverUtils
\r
305 .sortVirtualResources(intentVnMappingResult.getVirtualResource());
\r
307 VirtualNodeId virtualNodeId = new VirtualNodeId(virtualResources1.get(0)
\r
308 .getParentVirtualResourceEntityId().getValue());
\r
309 VirtualNode virtualNode = IntentResolverUtils.getVirtualNode(virtualNodes, virtualNodeId);
\r
311 if ( null == virtualNode ) {
\r
312 throw new IntentResolutionException("Can not get the virtual node" +
\r
313 " created for the first sub-node of the node " +
\r
314 intentVnMappingResult.getIntentId().getValue() + ".");
\r
317 virtualNodeId = new VirtualNodeId(virtualResources1.get(virtualResources1.size() - 1)
\r
318 .getParentVirtualResourceEntityId().getValue());
\r
319 VirtualNode virtualNode1 = IntentResolverUtils.getVirtualNode(virtualNodes, virtualNodeId);
\r
321 if ( null == virtualNode1 ) {
\r
322 throw new IntentResolutionException("Can not get the virtual node" +
\r
323 " created for the last sub-node of the node " +
\r
324 intentVnMappingResult.getIntentId().getValue() + ".");
\r
327 virtualResources = new ArrayList<VirtualResource>(virtualResources1.size() + 2);
\r
328 VirtualLink virtualLink = IntentResolverUtils.getVirtualLink(virtualLinks,
\r
329 sourceVirtualNode.getNodeId(), virtualNode.getNodeId());
\r
331 if ( null == virtualLink ) {
\r
332 VirtualPort virtualPort = new VirtualPortBuilder()
\r
333 .setPortId(new VirtualPortId(UUID.randomUUID().toString()))
\r
334 .setPortType(VirtualPort.PortType.Internal)
\r
336 sourceVirtualNode.getVirtualPort().add(virtualPort);
\r
338 VirtualPort virtualPort1 = new VirtualPortBuilder()
\r
339 .setPortId(new VirtualPortId(UUID.randomUUID().toString()))
\r
340 .setPortType(VirtualPort.PortType.Internal)
\r
342 virtualNode.getVirtualPort().add(virtualPort1);
\r
344 virtualLink = new VirtualLinkBuilder()
\r
345 .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))
\r
346 .setSrcNodeId(virtualNode.getNodeId())
\r
347 .setSrcPortId(virtualPort1.getPortId())
\r
348 .setDestNodeId(sourceVirtualNode.getNodeId())
\r
349 .setDestPortId(virtualPort.getPortId())
\r
352 virtualLinks.add(virtualLink);
\r
354 virtualLink = new VirtualLinkBuilder()
\r
355 .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))
\r
356 .setSrcNodeId(sourceVirtualNode.getNodeId())
\r
357 .setSrcPortId(virtualPort.getPortId())
\r
358 .setDestNodeId(virtualNode.getNodeId())
\r
359 .setDestPortId(virtualPort1.getPortId())
\r
362 virtualLinks.add(virtualLink);
\r
365 List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.path.instance.VirtualLink> virtualLinks1 =
\r
366 new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.path.instance.VirtualLink>(1);
\r
367 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.path.instance.VirtualLink virtualLink1 =
\r
368 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.path.instance.VirtualLinkBuilder()
\r
369 .setLinkId(virtualLink.getLinkId())
\r
372 virtualLinks1.add(virtualLink1);
\r
374 VirtualPath virtualPath = new VirtualPathBuilder()
\r
375 .setPathId(new VirtualPathId(UUID.randomUUID().toString()))
\r
376 .setVirtualLink(virtualLinks1)
\r
379 virtualPaths.add(virtualPath);
\r
381 VirtualResource virtualResource = new VirtualResourceBuilder()
\r
382 .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))
\r
383 .setVirtualResourceType(VirtualResource.VirtualResourceType.Vpath)
\r
384 .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualPath.getPathId().getValue()))
\r
387 virtualResources.add(virtualResource);
\r
389 for ( VirtualResource virtualResource1 : virtualResources1 ) {
\r
390 virtualResource = new VirtualResourceBuilder(virtualResource1)
\r
391 .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))
\r
392 .setOrder((long)virtualResources.size())
\r
394 virtualResources.add(virtualResource);
\r
397 virtualLink = IntentResolverUtils.getVirtualLink(virtualLinks,
\r
398 virtualNode1.getNodeId(), destinationVirtualNode.getNodeId());
\r
400 if ( null == virtualLink ) {
\r
401 VirtualPort virtualPort = new VirtualPortBuilder()
\r
402 .setPortId(new VirtualPortId(UUID.randomUUID().toString()))
\r
403 .setPortType(VirtualPort.PortType.Internal)
\r
405 virtualNode1.getVirtualPort().add(virtualPort);
\r
407 VirtualPort virtualPort1 = new VirtualPortBuilder()
\r
408 .setPortId(new VirtualPortId(UUID.randomUUID().toString()))
\r
409 .setPortType(VirtualPort.PortType.Internal)
\r
411 destinationVirtualNode.getVirtualPort().add(virtualPort1);
\r
413 virtualLink = new VirtualLinkBuilder()
\r
414 .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))
\r
415 .setSrcNodeId(destinationVirtualNode.getNodeId())
\r
416 .setSrcPortId(virtualPort1.getPortId())
\r
417 .setDestNodeId(virtualNode1.getNodeId())
\r
418 .setDestPortId(virtualPort.getPortId())
\r
421 virtualLinks.add(virtualLink);
\r
423 virtualLink = new VirtualLinkBuilder()
\r
424 .setLinkId(new VirtualLinkId(UUID.randomUUID().toString()))
\r
425 .setSrcNodeId(virtualNode1.getNodeId())
\r
426 .setSrcPortId(virtualPort.getPortId())
\r
427 .setDestNodeId(destinationVirtualNode.getNodeId())
\r
428 .setDestPortId(virtualPort1.getPortId())
\r
431 virtualLinks.add(virtualLink);
\r
434 virtualLinks1 = new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.path.instance.VirtualLink>(1);
\r
435 virtualLink1 = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.path.instance.VirtualLinkBuilder()
\r
436 .setLinkId(virtualLink.getLinkId())
\r
439 virtualLinks1.add(virtualLink1);
\r
441 virtualPath = new VirtualPathBuilder()
\r
442 .setPathId(new VirtualPathId(UUID.randomUUID().toString()))
\r
443 .setVirtualLink(virtualLinks1)
\r
446 virtualPaths.add(virtualPath);
\r
448 virtualResource = new VirtualResourceBuilder()
\r
449 .setVirtualResourceId(new VirtualResourceId(UUID.randomUUID().toString()))
\r
450 .setVirtualResourceType(VirtualResource.VirtualResourceType.Vpath)
\r
451 .setVirtualResourceEntityId(new VirtualResourceEntityId(virtualPath.getPathId().getValue()))
\r
452 .setOrder((long) virtualResources.size())
\r
454 virtualResources.add(virtualResource);
\r
462 IntentVnMappingResult intentVnMappingResult = new IntentVnMappingResultBuilder()
\r
463 .setIntentId(new IntentId(operation.getOperationId().getValue()))
\r
464 .setIntentType(IntentVnMappingResult.IntentType.Operation)
\r
465 .setVirtualResource(virtualResources)
\r
468 intentVnMappingResults.add(intentVnMappingResult);
\r