Modify intent handler.
[nemo.git] / nemo-impl / src / main / java / org / opendaylight / nemo / intent / IntentResolverUtils.java
1 /*\r
2  * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.\r
3  *\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
7  */\r
8 \r
9 package org.opendaylight.nemo.intent;\r
10 \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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.PhysicalNetwork;\r
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.hosts.PhysicalHost;\r
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.links.VirtualLink;\r
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.nodes.VirtualNode;\r
19 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
20 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
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.*;\r
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.PhysicalHostId;\r
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.PhysicalNodeId;\r
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.VirtualNodeId;\r
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.Objects;\r
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Connection;\r
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow;\r
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Node;\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.operations.Operation;\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.flow.instance.MatchItem;\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.node.instance.Property;\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.node.instance.SubNode;\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.property.instance.property.values.StringValue;\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.operation.rev151010.operation.instance.Action;\r
35 import org.opendaylight.yangtools.yang.binding.DataObject;\r
36 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
37 import org.slf4j.Logger;\r
38 import org.slf4j.LoggerFactory;\r
39 \r
40 import java.util.ArrayList;\r
41 import java.util.List;\r
42 import java.util.concurrent.ExecutionException;\r
43 \r
44 /**\r
45  * Implement the common utilities frequently used in\r
46  * the intent resolution.\r
47  *\r
48  * @author Zhigang Ji\r
49  */\r
50 public class IntentResolverUtils {\r
51     private static final Logger LOG = LoggerFactory.getLogger(IntentResolverUtils.class);\r
52 \r
53     /**\r
54      * Check whether the node is an external layer2 group or layer3 group.\r
55      *\r
56      * @param node The node to be checked.\r
57      * @return True if the node is an external layer3 group.\r
58      */\r
59     protected static boolean checkExternalLayer3Group(Node node) {\r
60         PropertyName propertyName = new PropertyName("ac-info-network");\r
61         Property property = getNodeProperty(node.getProperty(), propertyName);\r
62 \r
63         if ( null != property ) {\r
64             String propertyValue = property.getPropertyValues().getStringValue().get(0).getValue();\r
65 \r
66             if ( propertyValue.equals("layer3") ) {\r
67                 return true;\r
68             }\r
69         }\r
70 \r
71         return false;\r
72     }\r
73 \r
74     /**\r
75      * TODO\r
76      *\r
77      * @param physicalHosts TODO\r
78      * @param node TODO\r
79      * @return TODO\r
80      */\r
81     protected static PhysicalHost getPhysicalHost(List<PhysicalHost> physicalHosts, Node node) {\r
82         PhysicalHostId physicalHostId = new PhysicalHostId(node.getNodeId().getValue());\r
83 \r
84         return getPhysicalHost(physicalHosts, physicalHostId);\r
85     }\r
86 \r
87     /**\r
88      * TODO\r
89      *\r
90      * @param properties TODO\r
91      * @param propertyName TODO\r
92      * @return TODO\r
93      */\r
94     public static Property getNodeProperty(List<Property> properties, PropertyName propertyName) {\r
95         if ( null != properties ) {\r
96             for ( Property property : properties ) {\r
97                 if ( property.getPropertyName().equals(propertyName) ) {\r
98                     return property;\r
99                 }\r
100             }\r
101         }\r
102 \r
103         return null;\r
104     }\r
105 \r
106     /**\r
107      * TODO\r
108      *\r
109      * @param property TODO\r
110      * @return TODO\r
111      */\r
112     protected static PhysicalNodeId generatePhysicalNodeIdFromNodeLocationProperty(Property property) {\r
113         String propertyValue = property.getPropertyValues().getStringValue().get(0).getValue();\r
114 \r
115         return new PhysicalNodeId(propertyValue.substring(0, propertyValue.lastIndexOf(':')));\r
116     }\r
117 \r
118     /**\r
119      * TODO\r
120      *\r
121      * @param intentVnMappingResults TODO\r
122      * @param intentId TODO\r
123      * @return TODO\r
124      */\r
125     public static IntentVnMappingResult getIntentVnMappingResult(\r
126             List<IntentVnMappingResult> intentVnMappingResults, IntentId intentId) {\r
127         for ( IntentVnMappingResult intentVnMappingResult : intentVnMappingResults ) {\r
128             if ( intentVnMappingResult.getIntentId().equals(intentId) ) {\r
129                 return intentVnMappingResult;\r
130             }\r
131         }\r
132 \r
133         return null;\r
134     }\r
135 \r
136     /**\r
137      * TODO\r
138      *\r
139      * @param virtualNodes TODO\r
140      * @param virtualNodeId TODO\r
141      * @return TODO\r
142      */\r
143     public static VirtualNode getVirtualNode(List<VirtualNode> virtualNodes,\r
144                                              VirtualNodeId virtualNodeId) {\r
145         for ( VirtualNode virtualNode : virtualNodes ) {\r
146             if ( virtualNode.getNodeId().equals(virtualNodeId) ) {\r
147                 return virtualNode;\r
148             }\r
149         }\r
150 \r
151         return null;\r
152     }\r
153 \r
154     /**\r
155      * TODO\r
156      *\r
157      * @param nodes TODO\r
158      * @param nodeId TODO\r
159      * @return TODO\r
160      */\r
161     public static Node getNode(List<Node> nodes, NodeId nodeId) {\r
162         for ( Node node : nodes ) {\r
163             if ( node.getNodeId().equals(nodeId) ) {\r
164                 return node;\r
165             }\r
166         }\r
167 \r
168         return null;\r
169     }\r
170 \r
171     /**\r
172      * TODO\r
173      *\r
174      * @param properties TODO\r
175      * @param propertyName TODO\r
176      * @return TODO\r
177      */\r
178     public static org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.connection.instance.Property getConnectionProperty(\r
179             List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.connection.instance.Property> properties,\r
180             PropertyName propertyName) {\r
181         if ( null != properties ) {\r
182             for ( org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.object.rev151010.connection.instance.Property\r
183                     property : properties ) {\r
184                 if ( property.getPropertyName().equals(propertyName) ) {\r
185                     return property;\r
186                 }\r
187             }\r
188         }\r
189 \r
190         return null;\r
191     }\r
192 \r
193     /**\r
194      * TODO\r
195      *\r
196      * @param subNodes TODO\r
197      * @return TODO\r
198      */\r
199     protected static List<SubNode> sortSubNodes(List<SubNode> subNodes) {\r
200         if ( subNodes.isEmpty() || 1 == subNodes.size() ) {\r
201             return subNodes;\r
202         }\r
203 \r
204         List<SubNode> sortedSubNodes = new ArrayList<SubNode>(subNodes.size());\r
205         sortedSubNodes.addAll(subNodes);\r
206 \r
207         for ( SubNode subNode : subNodes ) {\r
208             sortedSubNodes.set(subNode.getOrder().intValue(), subNode);\r
209         }\r
210 \r
211         return sortedSubNodes;\r
212     }\r
213 \r
214     /**\r
215      * TODO\r
216      *\r
217      * @param subNodes TODO\r
218      * @param nodes TODO\r
219      * @return TODO\r
220      */\r
221     public static boolean checkAllLayer2OperatingMode(List<SubNode> subNodes, List<Node> nodes) {\r
222         if ( subNodes.isEmpty() ) {\r
223             return false;\r
224         }\r
225 \r
226         Node node;\r
227         PropertyName propertyName = new PropertyName("operating-mode");\r
228         Property property;\r
229         String propertyValue;\r
230 \r
231         for ( SubNode subNode : subNodes ) {\r
232             node = getNode(nodes, subNode.getNodeId());\r
233 \r
234             if ( null == node ) {\r
235                 return false;\r
236             }\r
237 \r
238             property = getNodeProperty(node.getProperty(), propertyName);\r
239 \r
240             if ( null == property ) {\r
241                 return false;\r
242             }\r
243 \r
244             propertyValue = property.getPropertyValues().getStringValue().get(0).getValue();\r
245 \r
246             if ( !propertyValue.equals("layer2") ) {\r
247                 return false;\r
248             }\r
249         }\r
250 \r
251         return true;\r
252     }\r
253 \r
254     /**\r
255      * TODO\r
256      *\r
257      * @param subNodes TODO\r
258      * @param nodes TODO\r
259      * @return TODO\r
260      */\r
261     public static boolean checkAllLayer3OperatingMode(List<SubNode> subNodes, List<Node> nodes) {\r
262         if ( subNodes.isEmpty() ) {\r
263             return false;\r
264         }\r
265 \r
266         Node node;\r
267         PropertyName propertyName = new PropertyName("operating-mode");\r
268         Property property;\r
269         String propertyValue;\r
270 \r
271         for ( SubNode subNode : subNodes ) {\r
272             node = getNode(nodes, subNode.getNodeId());\r
273 \r
274             if ( null == node ) {\r
275                 return false;\r
276             }\r
277 \r
278             property = getNodeProperty(node.getProperty(), propertyName);\r
279 \r
280             if ( null == property ) {\r
281                 return false;\r
282             }\r
283 \r
284             propertyValue = property.getPropertyValues().getStringValue().get(0).getValue();\r
285 \r
286             if ( !propertyValue.equals("layer3") ) {\r
287                 return false;\r
288             }\r
289         }\r
290 \r
291         return true;\r
292     }\r
293 \r
294     /**\r
295      * TODO\r
296      *\r
297      * @param virtualLinks TODO\r
298      * @param srcVirtualNodeId TODO\r
299      * @param destVirtualNodeId TODO\r
300      * @return TODO\r
301      */\r
302     public static VirtualLink getVirtualLink(List<VirtualLink> virtualLinks,\r
303                                              VirtualNodeId srcVirtualNodeId,\r
304                                              VirtualNodeId destVirtualNodeId) {\r
305         for ( VirtualLink virtualLink : virtualLinks ) {\r
306             if ( virtualLink.getSrcNodeId().equals(srcVirtualNodeId)\r
307                     && virtualLink.getDestNodeId().equals(destVirtualNodeId) ) {\r
308                 return virtualLink;\r
309             }\r
310         }\r
311 \r
312         return null;\r
313     }\r
314 \r
315     /**\r
316      * TODO\r
317      *\r
318      * @param objects TODO\r
319      * @param objectId TODO\r
320      * @return TODO\r
321      */\r
322     protected static DataObject getObject(Objects objects, ObjectId objectId) {\r
323         List<Node> nodes = objects.getNode();\r
324 \r
325         if ( null != nodes ) {\r
326             NodeId nodeId = new NodeId(objectId.getValue());\r
327             Node node = getNode(nodes, nodeId);\r
328 \r
329             if ( null != node ) {\r
330                 return node;\r
331             }\r
332         }\r
333 \r
334         List<Connection> connections = objects.getConnection();\r
335 \r
336         if ( null != connections ) {\r
337             ConnectionId connectionId = new ConnectionId(objectId.getValue());\r
338             Connection connection = getConnection(connections, connectionId);\r
339 \r
340             if ( null != connection ) {\r
341                 return connection;\r
342             }\r
343         }\r
344 \r
345         List<Flow> flows = objects.getFlow();\r
346 \r
347         if ( null != flows ) {\r
348             FlowId flowId = new FlowId(objectId.getValue());\r
349             Flow flow = getFlow(flows, flowId);\r
350 \r
351             if ( null != flow ) {\r
352                 return flow;\r
353             }\r
354         }\r
355 \r
356         return null;\r
357     }\r
358 \r
359     /**\r
360      * TODO\r
361      *\r
362      * @param operations TODO\r
363      * @param operation TODO\r
364      * @return TODO\r
365      */\r
366     protected static List<Operation> getSameTargetObjectOperations(List<Operation> operations,\r
367                                                                    Operation operation) {\r
368         // TODO\r
369 \r
370         return new ArrayList<Operation>(0);\r
371     }\r
372 \r
373     /**\r
374      * TODO\r
375      *\r
376      * @param operations TODO\r
377      * @param operation TODO\r
378      * @param greaterPriorityOperations TODO\r
379      * @param equalPriorityOperations TODO\r
380      */\r
381     protected static void getGreaterAndEqualPriorityOperations(List<Operation> operations, Operation operation,\r
382                                                                List<Operation> greaterPriorityOperations,\r
383                                                                List<Operation> equalPriorityOperations) {\r
384         // TODO\r
385 \r
386         return;\r
387     }\r
388 \r
389     /**\r
390      * TODO\r
391      *\r
392      * @param operations TODO\r
393      * @param operation TODO\r
394      * @return TODO\r
395      */\r
396     protected static Operation getConflictingOperation(List<Operation> operations,\r
397                                                        Operation operation) {\r
398         // TODO\r
399 \r
400         return null;\r
401     }\r
402 \r
403     /**\r
404      * TODO\r
405      *\r
406      * @param operations TODO\r
407      * @param operation TODO\r
408      * @return TODO\r
409      */\r
410     protected static List<Operation> getConflictingOperations(List<Operation> operations,\r
411                                                               Operation operation) {\r
412         // TODO\r
413 \r
414         return null;\r
415     }\r
416 \r
417     /**\r
418      * TODO\r
419      *\r
420      * @param physicalHosts TODO\r
421      * @param physicalHostId TODO\r
422      * @return TODO\r
423      */\r
424     private static PhysicalHost getPhysicalHost(List<PhysicalHost> physicalHosts,\r
425                                                 PhysicalHostId physicalHostId) {\r
426         for ( PhysicalHost physicalHost : physicalHosts ) {\r
427             if ( physicalHost.getHostId().equals(physicalHostId) ) {\r
428                 return physicalHost;\r
429             }\r
430         }\r
431 \r
432         return null;\r
433     }\r
434 \r
435     /**\r
436      * TODO\r
437      *\r
438      * @param connections TODO\r
439      * @param connectionId TODO\r
440      * @return TODO\r
441      */\r
442     private static Connection getConnection(List<Connection> connections, ConnectionId connectionId) {\r
443         for ( Connection connection : connections ) {\r
444             if ( connection.getConnectionId().equals(connectionId) ) {\r
445                 return connection;\r
446             }\r
447         }\r
448 \r
449         return null;\r
450     }\r
451 \r
452     /**\r
453      * TODO\r
454      *\r
455      * @param flows TODO\r
456      * @param flowId TODO\r
457      * @return TODO\r
458      */\r
459     private static Flow getFlow(List<Flow> flows, FlowId flowId) {\r
460         for ( Flow flow : flows ) {\r
461             if ( flow.getFlowId().equals(flowId) ) {\r
462                 return flow;\r
463             }\r
464         }\r
465 \r
466         return null;\r
467     }\r
468 \r
469     public static void copyPhysicalNetworkConfigToOperational(DataBroker dataBroker) {\r
470         final InstanceIdentifier<PhysicalNetwork> physicalNetworkIid = InstanceIdentifier\r
471                 .builder(PhysicalNetwork.class)\r
472                 .build();\r
473 \r
474         final ReadWriteTransaction txn = dataBroker.newReadWriteTransaction();\r
475 \r
476         try {\r
477             final Optional<PhysicalNetwork> oper = txn.read(LogicalDatastoreType.OPERATIONAL, physicalNetworkIid).get();\r
478 \r
479             if ( oper.isPresent() ) {\r
480                 PhysicalNetwork physicalNetwork = oper.get();\r
481 \r
482                 if ( null != physicalNetwork.getPhysicalNodes() ) {\r
483                     txn.cancel();\r
484                     LOG.info("Physical network already exists in operational");\r
485 \r
486                     return;\r
487                 }\r
488             }\r
489 \r
490             final Optional<PhysicalNetwork> config = txn.read(LogicalDatastoreType.CONFIGURATION,\r
491                     physicalNetworkIid).get();\r
492 \r
493             if (config.isPresent()) {\r
494                 txn.put(LogicalDatastoreType.OPERATIONAL, physicalNetworkIid, config.get());\r
495                 txn.submit().get();\r
496                 LOG.info("Copied physical network from config to operational");\r
497             } else {\r
498                 txn.cancel();\r
499                 LOG.info("No physical network found in config; none copied to operational");\r
500             }\r
501         } catch (InterruptedException exception) {\r
502             LOG.error("Cannot copy the physical network.", exception);\r
503         } catch (ExecutionException exception) {\r
504             LOG.error("Cannot copy the physical network.", exception);\r
505         }\r
506     }\r
507 }\r