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