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