Adding nemo engine.
[nemo.git] / nemo-impl / src / main / java / org / opendaylight / nemo / intent / IntentResolver.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.nemo.intent.computation.PNComputationUnit;\r
16 import org.opendaylight.nemo.intent.computation.VNComputationUnit;\r
17 import org.opendaylight.nemo.intent.computation.VNMappingUnit;\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.PhysicalPaths;\r
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.paths.PhysicalPath;\r
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.paths.PhysicalPathKey;\r
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.VirtualNetworks;\r
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.VirtualNetwork;\r
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.VirtualNetworkBuilder;\r
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.VirtualNetworkKey;\r
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.*;\r
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.arps.VirtualArp;\r
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.links.VirtualLink;\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.nodes.VirtualNode;\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.paths.VirtualPath;\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.virtual.network.virtual.routes.VirtualRoute;\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.IntentVnMappingResults;\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.VnPnMappingResults;\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.UserIntentVnMapping;\r
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.UserIntentVnMappingBuilder;\r
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.UserIntentVnMappingKey;\r
37 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
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.vn.pn.mapping.results.UserVnPnMapping;\r
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.vn.pn.mapping.results.UserVnPnMappingBuilder;\r
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.vn.pn.mapping.results.UserVnPnMappingKey;\r
41 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
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.NodeType;\r
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.PhysicalPathId;\r
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.VirtualNetworkId;\r
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.Users;\r
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Connection;\r
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Flow;\r
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.objects.Node;\r
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.user.intent.operations.Operation;\r
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.UserKey;\r
53 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
54 import org.slf4j.Logger;\r
55 import org.slf4j.LoggerFactory;\r
56 \r
57 import java.util.HashMap;\r
58 import java.util.LinkedList;\r
59 import java.util.List;\r
60 import java.util.Map;\r
61 import java.util.concurrent.ExecutionException;\r
62 \r
63 /**\r
64  * Provide the user intent resolution APIs and distribute the user intents\r
65  * to corresponding handling classes.\r
66  *\r
67  * @author Zhigang Ji\r
68  */\r
69 public class IntentResolver implements AutoCloseable {\r
70     private static final Logger LOG = LoggerFactory.getLogger(IntentResolver.class);\r
71 \r
72     private final DataBroker dataBroker;\r
73 \r
74     /**\r
75      * The node mapper to resolve the user's node intent.\r
76      */\r
77     private NodeMapper nodeMapper;\r
78 \r
79     /**\r
80      * The connection mapper to resolve the user's connection intent.\r
81      */\r
82     private ConnectionMapper connectionMapper;\r
83 \r
84     /**\r
85      * The flow manager to resolve the user's flow intent.\r
86      */\r
87     private FlowManager flowManager;\r
88 \r
89     /**\r
90      * The operation resolver to resolve the user's operation intent.\r
91      */\r
92     private OperationResolver operationResolver;\r
93 \r
94     /**\r
95      * The physical network computation unit.\r
96      */\r
97     private PNComputationUnit pnComputationUnit;\r
98 \r
99     /**\r
100      * The virtual network computation unit for all users.\r
101      */\r
102     private Map<UserId, VNComputationUnit> vnComputationUnits;\r
103 \r
104     /**\r
105      * The virtual network mapping unit.\r
106      */\r
107     private VNMappingUnit vnMappingUnit;\r
108 \r
109     public IntentResolver(DataBroker dataBroker) {\r
110         super();\r
111 \r
112         this.dataBroker = dataBroker;\r
113 \r
114         nodeMapper = new NodeMapper(dataBroker);\r
115         connectionMapper = new ConnectionMapper(dataBroker, nodeMapper);\r
116         flowManager = new FlowManager(dataBroker);\r
117         operationResolver = new OperationResolver(dataBroker);\r
118 \r
119         pnComputationUnit = new PNComputationUnit(dataBroker);\r
120         vnComputationUnits = new HashMap<UserId, VNComputationUnit>();\r
121         vnMappingUnit = new VNMappingUnit(dataBroker, pnComputationUnit);\r
122 \r
123         LOG.debug("Initialized the renderer common intent resolver.");\r
124 \r
125         return;\r
126     }\r
127 \r
128     /**\r
129      * Resolve the user's intents to generate the virtual network, then map\r
130      * the virtual network into the underlying physical network, finally, store\r
131      * the generated intent mapping results into the data store, and various\r
132      * renderers configure the underlying networks according to these results.\r
133      *\r
134      * @param userId The user id for the intents to be resolved.\r
135      */\r
136     public void resolveIntent(UserId userId) throws Exception {\r
137         VNComputationUnit vnComputationUnit = vnComputationUnits.get(userId);\r
138 \r
139         VirtualNetworkId virtualNetworkId = new VirtualNetworkId(userId.getValue());\r
140         VirtualNetworkKey virtualNetworkKey = new VirtualNetworkKey(virtualNetworkId);\r
141 \r
142         InstanceIdentifier<VirtualNetwork> virtualNetworkIid = InstanceIdentifier\r
143                 .builder(VirtualNetworks.class)\r
144                 .child(VirtualNetwork.class, virtualNetworkKey)\r
145                 .build();\r
146         InstanceIdentifier<UserIntentVnMapping> userIntentVnMappingIid = InstanceIdentifier\r
147                 .builder(IntentVnMappingResults.class)\r
148                 .child(UserIntentVnMapping.class, new UserIntentVnMappingKey(userId))\r
149                 .build();\r
150         InstanceIdentifier<UserVnPnMapping> userVnPnMappingIid = InstanceIdentifier\r
151                 .builder(VnPnMappingResults.class)\r
152                 .child(UserVnPnMapping.class, new UserVnPnMappingKey(virtualNetworkId))\r
153                 .build();\r
154 \r
155         if ( null != vnComputationUnit ) {\r
156             vnComputationUnit.close();\r
157             vnComputationUnits.remove(userId);\r
158 \r
159             ReadWriteTransaction readWriteTransaction = dataBroker.newReadWriteTransaction();\r
160 \r
161             Optional<UserVnPnMapping> result;\r
162 \r
163             try {\r
164                 result = readWriteTransaction.read(LogicalDatastoreType.CONFIGURATION, userVnPnMappingIid).get();\r
165             } catch ( InterruptedException | ExecutionException exception ) {\r
166                 throw new IntentResolutionException("Can not read the vn-pn mapping results for the user " +\r
167                         userId.getValue() + ".");\r
168             }\r
169 \r
170             if ( result.isPresent() ) {\r
171                 UserVnPnMapping userVnPnMapping = result.get();\r
172                 List<VnPnMappingResult> vnPnMappingResults = userVnPnMapping.getVnPnMappingResult();\r
173                 InstanceIdentifier<PhysicalPath> physicalPathIid;\r
174                 PhysicalPathId physicalPathId;\r
175 \r
176                 for ( VnPnMappingResult vnPnMappingResult : vnPnMappingResults ) {\r
177                     if ( VnPnMappingResult.VirtualResourceType.Vlink == vnPnMappingResult.getVirtualResourceType() ) {\r
178                         physicalPathId = new PhysicalPathId(vnPnMappingResult.getPhysicalResourceEntityId().getValue());\r
179                         physicalPathIid = InstanceIdentifier.builder(PhysicalNetwork.class)\r
180                                 .child(PhysicalPaths.class)\r
181                                 .child(PhysicalPath.class, new PhysicalPathKey(physicalPathId))\r
182                                 .build();\r
183 \r
184                         readWriteTransaction.delete(LogicalDatastoreType.OPERATIONAL, physicalPathIid);\r
185                     }\r
186                 }\r
187             }\r
188 \r
189 //            readWriteTransaction.delete(LogicalDatastoreType.CONFIGURATION, virtualNetworkIid);\r
190 //            readWriteTransaction.delete(LogicalDatastoreType.CONFIGURATION, userIntentVnMappingIid);\r
191 //            readWriteTransaction.delete(LogicalDatastoreType.CONFIGURATION, userVnPnMappingIid);\r
192             // TODO: åˆ é™¤intent processing status\r
193 \r
194             readWriteTransaction.submit();\r
195         }\r
196 \r
197         ReadWriteTransaction readWriteTransaction = dataBroker.newReadWriteTransaction();\r
198 \r
199         InstanceIdentifier<User> userIid = InstanceIdentifier.builder(Users.class)\r
200                 .child(User.class, new UserKey(userId))\r
201                 .build();\r
202         Optional<User> result;\r
203 \r
204         try {\r
205             result = readWriteTransaction.read(LogicalDatastoreType.CONFIGURATION, userIid).get();\r
206         } catch ( InterruptedException | ExecutionException exception ) {\r
207             throw new IntentResolutionException("Can not read the data of the user " +\r
208                     userId.getValue() + ".");\r
209         }\r
210 \r
211         if ( !result.isPresent() ) {\r
212             throw new IntentResolutionException("The data of the user " +\r
213                     userId.getValue() + " does not exist.");\r
214         }\r
215 \r
216         User user = result.get();\r
217 \r
218         if ( null != user.getObjects() ) {\r
219             VirtualNodes virtualNodes = new VirtualNodesBuilder()\r
220                     .setVirtualNode(new LinkedList<VirtualNode>())\r
221                     .build();\r
222             VirtualLinks virtualLinks = new VirtualLinksBuilder()\r
223                     .setVirtualLink(new LinkedList<VirtualLink>())\r
224                     .build();\r
225             VirtualPaths virtualPaths = new VirtualPathsBuilder()\r
226                     .setVirtualPath(new LinkedList<VirtualPath>())\r
227                     .build();\r
228             VirtualRoutes virtualRoutes = new VirtualRoutesBuilder()\r
229                     .setVirtualRoute(new LinkedList<VirtualRoute>())\r
230                     .build();\r
231             VirtualArps virtualArps = new VirtualArpsBuilder()\r
232                     .setVirtualArp(new LinkedList<VirtualArp>())\r
233                     .build();\r
234             VirtualNetwork virtualNetwork = new VirtualNetworkBuilder()\r
235                     .setNetworkId(virtualNetworkId)\r
236                     .setUserId(userId)\r
237                     .setVirtualNodes(virtualNodes)\r
238                     .setVirtualLinks(virtualLinks)\r
239                     .setVirtualPaths(virtualPaths)\r
240                     .setVirtualRoutes(virtualRoutes)\r
241                     .setVirtualArps(virtualArps)\r
242                     .build();\r
243 \r
244             UserIntentVnMapping userIntentVnMapping = new UserIntentVnMappingBuilder()\r
245                     .setUserId(userId)\r
246                     .setVirtualNetworkId(virtualNetworkId)\r
247                     .setIntentVnMappingResult(new LinkedList<IntentVnMappingResult>())\r
248                     .build();\r
249 \r
250             UserVnPnMapping userVnPnMapping = new UserVnPnMappingBuilder()\r
251                     .setVirtualNetworkId(virtualNetworkId)\r
252                     .setUserId(userId)\r
253                     .setVnPnMappingResult(new LinkedList<VnPnMappingResult>())\r
254                     .build();\r
255 \r
256             List<PhysicalPath> physicalPaths = new LinkedList<PhysicalPath>();\r
257 \r
258             List<Node> nodes = user.getObjects().getNode();\r
259             List<Node> hosts = new LinkedList<Node>();\r
260             List<Node> layer2Groups = new LinkedList<Node>();\r
261             List<Node> layer3Groups = new LinkedList<Node>();\r
262             List<Node> externalLayer3Groups = new LinkedList<Node>();\r
263             List<Node> serviceChainGroups = new LinkedList<Node>();\r
264             List<Node> serviceFunctions = new LinkedList<Node>();\r
265 \r
266             NodeType hostNodeType = new NodeType("host");\r
267             NodeType layer2GroupNodeType = new NodeType("l2-group");\r
268             NodeType layer3GroupNodeType = new NodeType("l3-group");\r
269             NodeType externalGroupNodeType = new NodeType("ext-group");\r
270             NodeType serviceChainGroupNodeType = new NodeType("chain-group");\r
271             NodeType firewallNodeType = new NodeType("fw");\r
272             NodeType loadbalancerNodeType = new NodeType("lb");\r
273             NodeType cacheNodeType = new NodeType("cache");\r
274             NodeType nodeType;\r
275 \r
276             if ( null != nodes ) {\r
277                 for ( Node node : nodes ) {\r
278                     nodeType = node.getNodeType();\r
279 \r
280                     if ( nodeType.equals(hostNodeType) ) {\r
281                         hosts.add(node);\r
282                     }\r
283 \r
284                     if ( nodeType.equals(layer2GroupNodeType) ) {\r
285                         layer2Groups.add(node);\r
286                     }\r
287 \r
288                     if ( nodeType.equals(layer3GroupNodeType) ) {\r
289                         layer3Groups.add(node);\r
290                     }\r
291 \r
292                     if ( nodeType.equals(externalGroupNodeType) ) {\r
293                         if ( IntentResolverUtils.checkExternalLayer3Group(node) ) {\r
294                             externalLayer3Groups.add(node);\r
295                         }\r
296                     }\r
297 \r
298                     if ( nodeType.equals(serviceChainGroupNodeType) ) {\r
299                         serviceChainGroups.add(node);\r
300                     }\r
301 \r
302                     if ( nodeType.equals(firewallNodeType)\r
303                             || nodeType.equals(loadbalancerNodeType)\r
304                             || nodeType.equals(cacheNodeType) ) {\r
305                         serviceFunctions.add(node);\r
306                     }\r
307                 }\r
308 \r
309                 for ( Node node : hosts ) {\r
310                     nodeMapper.resolveHost(user, node, virtualNetwork, userIntentVnMapping);\r
311                 }\r
312 \r
313                 for ( Node node : layer2Groups ) {\r
314                     nodeMapper.resolveLayer2Group(user, node, virtualNetwork, userIntentVnMapping);\r
315                 }\r
316 \r
317                 for ( Node node : externalLayer3Groups ) {\r
318                     nodeMapper.resolveExternalLayer3Group(user, node, virtualNetwork, userIntentVnMapping);\r
319                 }\r
320 \r
321                 for ( Node node : layer3Groups ) {\r
322                     nodeMapper.resolveLayer3Group(user, node, virtualNetwork, userIntentVnMapping);\r
323                 }\r
324 \r
325                 for ( Node node : serviceFunctions ) {\r
326                     nodeMapper.resolveServiceFunction(user, node, virtualNetwork, userIntentVnMapping);\r
327                 }\r
328 \r
329                 for ( Node node : serviceChainGroups ) {\r
330                     nodeMapper.resolveServiceChainGroup(user, node, virtualNetwork, userIntentVnMapping);\r
331                 }\r
332             }\r
333 \r
334             List<Connection> connections = user.getObjects().getConnection();\r
335 \r
336             if ( null != connections ) {\r
337                 for ( Connection connection : connections ) {\r
338                     connectionMapper.resolveConnection(user, connection, virtualNetwork, userIntentVnMapping);\r
339                 }\r
340             }\r
341 \r
342             List<Flow> flows = user.getObjects().getFlow();\r
343 \r
344             if ( null != flows ) {\r
345                 for ( Flow flow : flows ) {\r
346                     flowManager.resolveFlow(userId, flow);\r
347                 }\r
348             }\r
349 \r
350             if ( null != user.getOperations() ) {\r
351                 List<Operation> operations = user.getOperations().getOperation();\r
352 \r
353                 if ( null != operations ) {\r
354                     for ( Operation operation : operations ) {\r
355                         operationResolver.resolveOperation(user, operation, virtualNetwork, userIntentVnMapping);\r
356                     }\r
357                 }\r
358             }\r
359 \r
360             vnMappingUnit.virtualNetworkMapping(virtualNetwork, userVnPnMapping, physicalPaths);\r
361             vnComputationUnit = new VNComputationUnit(dataBroker, virtualNetwork);\r
362             vnComputationUnits.put(userId, vnComputationUnit);\r
363 \r
364             // for testing - jizhigang\r
365             System.out.println(virtualNetwork);\r
366             System.out.println(userIntentVnMapping);\r
367             System.out.println(userVnPnMapping);\r
368             System.out.println(physicalPaths);\r
369             // for testing - jizhigang\r
370 \r
371             readWriteTransaction.put(LogicalDatastoreType.CONFIGURATION, virtualNetworkIid, virtualNetwork, true);\r
372             readWriteTransaction.put(LogicalDatastoreType.CONFIGURATION, userIntentVnMappingIid, userIntentVnMapping, true);\r
373             readWriteTransaction.put(LogicalDatastoreType.CONFIGURATION, userVnPnMappingIid, userVnPnMapping, true);\r
374 \r
375             InstanceIdentifier<PhysicalPath> physicalPathIid;\r
376 \r
377             for ( PhysicalPath physicalPath : physicalPaths ) {\r
378                 physicalPathIid = InstanceIdentifier.builder(PhysicalNetwork.class)\r
379                         .child(PhysicalPaths.class)\r
380                         .child(PhysicalPath.class, new PhysicalPathKey(physicalPath.getPathId()))\r
381                         .build();\r
382 \r
383                 readWriteTransaction.put(LogicalDatastoreType.OPERATIONAL, physicalPathIid, physicalPath, true);\r
384             }\r
385 \r
386             readWriteTransaction.submit();\r
387         }\r
388 \r
389         return;\r
390     }\r
391 \r
392     @Override\r
393     public void close() throws Exception {\r
394         if ( null != pnComputationUnit ) {\r
395             pnComputationUnit.close();\r
396         }\r
397 \r
398         for ( VNComputationUnit vnComputationUnit : vnComputationUnits.values() ) {\r
399             if ( null != vnComputationUnit ) {\r
400                 vnComputationUnit.close();\r
401             }\r
402         }\r
403 \r
404         if ( null != vnMappingUnit ) {\r
405             vnMappingUnit.close();\r
406         }\r
407 \r
408         return;\r
409     }\r
410 }\r