Adding nemo engine.
[nemo.git] / nemo-renderers / openflow-renderer / src / main / java / org / opendaylight / nemo / renderer / openflow / FlowTableManager.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.renderer.openflow;\r
10 \r
11 import com.google.common.base.Optional;\r
12 import com.google.common.util.concurrent.FutureCallback;\r
13 import com.google.common.util.concurrent.Futures;\r
14 \r
15 import java.util.ArrayList;\r
16 import java.util.List;\r
17 import java.util.concurrent.Executors;\r
18 import java.util.concurrent.ScheduledExecutorService;\r
19 import com.google.common.util.concurrent.CheckedFuture;\r
20 \r
21 import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
22 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;\r
23 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;\r
24 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;\r
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
26 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;\r
27 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;\r
28 \r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.PhysicalNetwork;\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.PhysicalNodes;\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.nodes.PhysicalNode;\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.VirtualNetworks;\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.VirtualNetwork;\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.virtual.network.rev151010.virtual.networks.VirtualNetworkKey;\r
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.IntentVnMappingResults;\r
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.VnPnMappingResults;\r
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.intent.mapping.result.rev151010.intent.vn.mapping.results.UserIntentVnMapping;\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.vn.pn.mapping.results.UserVnPnMapping;\r
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.VirtualNetworkId;\r
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.common.rev151010.UserId;\r
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.Users;\r
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.User;\r
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.intent.rev151010.users.UserKey;\r
45 import org.opendaylight.yangtools.concepts.ListenerRegistration;\r
46 import org.opendaylight.yangtools.yang.binding.DataObject;\r
47 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
48 \r
49 \r
50 import org.slf4j.Logger;\r
51 import org.slf4j.LoggerFactory;\r
52 \r
53 import java.util.Map;\r
54 import java.util.Set;\r
55 \r
56 public class FlowTableManager implements AutoCloseable {\r
57     private static final Logger LOG = LoggerFactory.getLogger(FlowTableManager.class);\r
58 \r
59     private final DataBroker dataProvider;\r
60 \r
61     private ListenerRegistration<DataChangeListener> userVnPnMappingChangeListenerReg;\r
62 \r
63     private FlowUtils flowUtils = null;\r
64 \r
65     public FlowTableManager(DataBroker dataProvider, ResourceManager resourceManager){\r
66 \r
67         this.dataProvider = dataProvider;\r
68         LOG.info("Initialized FlowTableManager.");\r
69         flowUtils = new FlowUtils(dataProvider, resourceManager);\r
70         //register  listener\r
71         registerUserVnPnMappingListener();\r
72     }\r
73 \r
74     private void registerUserVnPnMappingListener() {\r
75 \r
76         //build userVnPnMappingIid\r
77         InstanceIdentifier<UserVnPnMapping> userVnPnMappingIid = InstanceIdentifier\r
78                 .builder(VnPnMappingResults.class)\r
79                 .child(UserVnPnMapping.class)\r
80                 .build();\r
81         //register\r
82         userVnPnMappingChangeListenerReg = dataProvider.registerDataChangeListener(\r
83                 LogicalDatastoreType.CONFIGURATION, userVnPnMappingIid,\r
84                 new UserVnPnMappingChangeListener(), DataChangeScope.BASE);\r
85     }\r
86 \r
87 \r
88     private User getUser(UserId userId) {\r
89 \r
90         ReadOnlyTransaction readOnlyTransaction = dataProvider.newReadOnlyTransaction();\r
91         InstanceIdentifier<User> userIid = InstanceIdentifier.builder(Users.class)\r
92                 .child(User.class, new UserKey(userId))\r
93                 .build();\r
94         Optional<User> result = null;\r
95 \r
96         try {\r
97             result = readOnlyTransaction.read(LogicalDatastoreType.CONFIGURATION, userIid).get();\r
98         } catch (Exception e) {\r
99             e.printStackTrace();\r
100         }\r
101         if (result.isPresent()){\r
102             LOG.info("getUser  OK");\r
103             return (result.get());\r
104 \r
105         }else{\r
106             LOG.info("getUser  ERROR");\r
107             return  null;\r
108         }\r
109     }\r
110 \r
111 \r
112     private  VirtualNetwork getVirtualNetwork(UserId userId) {\r
113 \r
114         VirtualNetworkId virtualNetworkId = new VirtualNetworkId(userId.getValue());\r
115         VirtualNetworkKey virtualNetworkKey = new VirtualNetworkKey(virtualNetworkId);\r
116 \r
117         ReadOnlyTransaction readOnlyTransaction = dataProvider.newReadOnlyTransaction();\r
118         InstanceIdentifier<VirtualNetwork> virtualNetworkIid = InstanceIdentifier\r
119                 .builder(VirtualNetworks.class)\r
120                 .child(VirtualNetwork.class, virtualNetworkKey)\r
121                 .build();\r
122         Optional<VirtualNetwork> result = null;\r
123 \r
124         try {\r
125             result = readOnlyTransaction.read(LogicalDatastoreType.CONFIGURATION, virtualNetworkIid).get();\r
126 \r
127         } catch (Exception e) {\r
128             e.printStackTrace();\r
129         }\r
130         if (result.isPresent()) {\r
131             LOG.info("getVirtualNetwork  OK");\r
132             return (result.get());\r
133 \r
134         }else{\r
135             LOG.info("getVirtualNetwork  ERROR");\r
136             return  null;\r
137         }\r
138     }\r
139 \r
140     private  UserIntentVnMapping getUserIntentVnMapping(UserId userId) {\r
141 \r
142         ReadOnlyTransaction readOnlyTransaction = dataProvider.newReadOnlyTransaction();\r
143         InstanceIdentifier<UserIntentVnMapping> userIntentVnMappingIid = InstanceIdentifier\r
144                 .builder(IntentVnMappingResults.class)\r
145                 .child(UserIntentVnMapping.class, new UserIntentVnMappingKey(userId))\r
146                 .build();\r
147         Optional<UserIntentVnMapping> result = null;\r
148         try {\r
149             result = readOnlyTransaction.read(LogicalDatastoreType.CONFIGURATION, userIntentVnMappingIid).get();\r
150         } catch (Exception e) {\r
151             e.printStackTrace();\r
152         }\r
153         if (result.isPresent()) {\r
154             LOG.info("getUserIntentVnMapping  OK");\r
155             return (result.get());\r
156 \r
157         }else{\r
158             LOG.info("getUserIntentVnMapping  ERROR");\r
159             return  null;\r
160         }\r
161     }\r
162 \r
163     private PhysicalNetwork getPhysicalNetwork() {\r
164 \r
165         ReadOnlyTransaction readOnlyTransaction = dataProvider.newReadOnlyTransaction();\r
166         InstanceIdentifier<PhysicalNetwork> physicalNetworkIid = InstanceIdentifier\r
167                 .builder(PhysicalNetwork.class)\r
168                 .build();\r
169         Optional<PhysicalNetwork> result = null;\r
170         try {\r
171             result = readOnlyTransaction.read(LogicalDatastoreType.OPERATIONAL, physicalNetworkIid).get();\r
172         } catch (Exception e) {\r
173             e.printStackTrace();\r
174         }\r
175         if (result.isPresent()) {\r
176             LOG.info("getPhysicalNetwork  OK");\r
177             return (result.get());\r
178 \r
179         }else{\r
180             LOG.info("getPhysicalNetwork  ERROR");\r
181             return  null;\r
182         }\r
183     }\r
184 \r
185 \r
186     //A listener implementation\r
187     private class UserVnPnMappingChangeListener implements DataChangeListener {\r
188 \r
189         @Override\r
190         public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {\r
191             if ( null == change ) {\r
192                 return;\r
193             }\r
194 \r
195             Map<InstanceIdentifier<?>, DataObject> createdData = change.getCreatedData();\r
196             if ( null != createdData && !createdData.isEmpty() ) {\r
197                 for ( DataObject dataObject : createdData.values() ) {\r
198                     if ( dataObject instanceof UserVnPnMapping ) {\r
199                         LOG.info("Ready to update flow table.");\r
200                         UserVnPnMapping userVnPnMapping = (UserVnPnMapping)dataObject;\r
201                         UserId userId = userVnPnMapping.getUserId();\r
202 \r
203                         User user = getUser(userId);\r
204                         VirtualNetwork virtualNetwork = getVirtualNetwork(userId);\r
205                         UserIntentVnMapping userIntentVnMapping = getUserIntentVnMapping(userId);\r
206                         PhysicalNetwork physicalNetwork = getPhysicalNetwork();\r
207                         if(physicalNetwork == null)\r
208                         {\r
209                             LOG.debug("Physical Network data are not present.");\r
210                             return;\r
211                         }\r
212                         PhysicalNodes physicalNodes= physicalNetwork.getPhysicalNodes();\r
213                         List<PhysicalNode> physicalNodeList = physicalNodes.getPhysicalNode();\r
214                         flowUtils.init(physicalNodeList);\r
215 \r
216                         flowUtils.updateFlowTable(user, virtualNetwork, userIntentVnMapping, userVnPnMapping, physicalNetwork);\r
217                         LOG.info("Already call flowUtils.updateFlowTable().");\r
218                     }\r
219                 }\r
220             }\r
221 \r
222             Map<InstanceIdentifier<?>, DataObject> updatedData = change.getUpdatedData();\r
223             if ( null != updatedData && !updatedData.isEmpty() ) {\r
224                 for ( DataObject dataObject : updatedData.values() ) {\r
225                     if ( dataObject instanceof UserVnPnMapping ) {\r
226                         UserVnPnMapping userVnPnMapping = (UserVnPnMapping)dataObject;\r
227                         UserId userId = userVnPnMapping.getUserId();\r
228 \r
229                         flowUtils.deleteFlowEntries(userId);\r
230 \r
231                         User user = getUser(userId);\r
232                         VirtualNetwork virtualNetwork = getVirtualNetwork(userId);\r
233                         UserIntentVnMapping userIntentVnMapping = getUserIntentVnMapping(userId);\r
234                         PhysicalNetwork physicalNetwork = getPhysicalNetwork();\r
235                         if(physicalNetwork == null)\r
236                         {\r
237                             LOG.debug("Physical Network data are not present.");\r
238                             return;\r
239                         }\r
240 \r
241                         flowUtils.updateFlowTable(user, virtualNetwork, userIntentVnMapping, userVnPnMapping, physicalNetwork);\r
242                     }\r
243                 }\r
244             }\r
245 \r
246             Map<InstanceIdentifier<?>, DataObject> originalData = change.getOriginalData();\r
247             Set<InstanceIdentifier<?>> removedPaths = change.getRemovedPaths();\r
248             if ( null != removedPaths && !removedPaths.isEmpty() ) {\r
249                 DataObject dataObject;\r
250 \r
251                 for ( InstanceIdentifier<?> instanceId : removedPaths ) {\r
252                     dataObject = originalData.get(instanceId);\r
253                     if ( null != dataObject && dataObject instanceof UserVnPnMapping ) {\r
254                         UserVnPnMapping userVnPnMapping = (UserVnPnMapping)dataObject;\r
255                         flowUtils.deleteFlowEntries(userVnPnMapping.getUserId());\r
256                     }\r
257                 }\r
258             }\r
259             return;\r
260         }\r
261     }\r
262 \r
263     @Override\r
264     public void close() throws Exception {\r
265 \r
266         if ( null != userVnPnMappingChangeListenerReg ) {\r
267             userVnPnMappingChangeListenerReg.close();\r
268         }\r
269         if ( null != flowUtils ) {\r
270             flowUtils.close();\r
271         }\r
272     }\r
273 }\r