Added new FlowTables (NATMapper, ExternalMapper)
[groupbasedpolicy.git] / renderers / ofoverlay / src / main / java / org / opendaylight / groupbasedpolicy / integration / openstackgbp / OpenstackGbpEndpoint.java
1 package org.opendaylight.groupbasedpolicy.integration.openstackgbp;
2
3 import java.util.ArrayList;
4 import java.util.List;
5 import java.util.concurrent.ExecutionException;
6 import java.util.concurrent.Executors;
7 import java.util.concurrent.Future;
8 import java.util.concurrent.ScheduledExecutorService;
9
10 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
11 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
12 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
13 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
14 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
15 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
16 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
17 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
18 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.Endpoints;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContextBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.openstackendpoint.rev141204.OpenstackEndpoints;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.openstackendpoint.rev141204.OpenstackEndpointsBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.openstackendpoint.rev141204.OpenstackEndpointService;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.openstackendpoint.rev141204.RegisterEndpointInput;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.openstackendpoint.rev141204.UnregisterEndpointInput;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.openstackendpoint.rev141204.endpoint.fields.L3Address;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.openstackendpoint.rev141204.openstack.endpoints.Endpoint;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.openstackendpoint.rev141204.openstack.endpoints.EndpointBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.openstackendpoint.rev141204.openstack.endpoints.EndpointKey;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.openstackendpoint.rev141204.openstack.endpoints.EndpointL3;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.openstackendpoint.rev141204.openstack.endpoints.EndpointL3Builder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.openstackendpoint.rev141204.openstack.endpoints.EndpointL3Key;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.openstackendpoint.rev141204.unregister.endpoint.input.L2;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.openstackendpoint.rev141204.unregister.endpoint.input.L3;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
42 import org.opendaylight.yangtools.concepts.ListenerRegistration;
43 import org.opendaylight.yangtools.yang.binding.DataObject;
44 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
45 import org.opendaylight.yangtools.yang.common.RpcResult;
46 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50 import com.google.common.base.Function;
51 import com.google.common.base.Optional;
52 import com.google.common.util.concurrent.CheckedFuture;
53 import com.google.common.util.concurrent.FutureCallback;
54 import com.google.common.util.concurrent.Futures;
55 import com.google.common.util.concurrent.ListenableFuture;
56
57 /*
58  * TODO: Remove YANG for this class, and other OpenStackGBP APIs,
59  * this has been replaced by standard API in Kilo and backported to Juno
60 */
61 @Deprecated
62 public class OpenstackGbpEndpoint implements AutoCloseable,
63         OpenstackEndpointService {
64
65     public static final InstanceIdentifier<OpenstackEndpoints> OPENSTACKEP_IID = InstanceIdentifier
66             .builder(OpenstackEndpoints.class).build();
67
68     private static final Logger LOG = LoggerFactory
69             .getLogger(OpenstackGbpEndpoint.class);
70
71     private DataBroker dataProvider;
72     private final ScheduledExecutorService executor;
73
74     private final static InstanceIdentifier<Nodes> nodesIid = InstanceIdentifier
75             .builder(Nodes.class).build();
76     private final static InstanceIdentifier<Node> nodeIid = InstanceIdentifier
77             .builder(Nodes.class).child(Node.class).build();
78     private ListenerRegistration<DataChangeListener> nodesReg;
79
80     final BindingAwareBroker.RpcRegistration<OpenstackEndpointService> rpcRegistration;
81
82     public OpenstackGbpEndpoint(DataBroker dataProvider,
83             RpcProviderRegistry rpcRegistry) {
84         super();
85         this.dataProvider = dataProvider;
86         executor = Executors.newScheduledThreadPool(1);
87
88         if (rpcRegistry != null) {
89             rpcRegistration = rpcRegistry.addRpcImplementation(
90                     OpenstackEndpointService.class, this);
91         } else
92             rpcRegistration = null;
93
94         if (dataProvider != null) {
95             InstanceIdentifier<OpenstackEndpoints> iid = InstanceIdentifier
96                     .builder(OpenstackEndpoints.class).build();
97             WriteTransaction t = this.dataProvider.newWriteOnlyTransaction();
98             t.put(LogicalDatastoreType.OPERATIONAL, iid,
99                     new OpenstackEndpointsBuilder().build());
100             CheckedFuture<Void, TransactionCommitFailedException> f = t
101                     .submit();
102             Futures.addCallback(f, new FutureCallback<Void>() {
103                 @Override
104                 public void onFailure(Throwable t) {
105                     LOG.error("Could not write endpoint base container", t);
106                 }
107
108                 @Override
109                 public void onSuccess(Void result) {
110                 }
111             });
112             nodesReg = dataProvider.registerDataChangeListener(
113                     LogicalDatastoreType.OPERATIONAL, nodeIid,
114                     new NodesListener(), DataChangeScope.SUBTREE);
115         }
116     }
117
118     public void setDataProvider(final DataBroker salDataProvider) {
119         this.dataProvider = salDataProvider;
120     }
121
122     @Override
123     public void close() throws Exception {
124         // When we close this service we need to shutdown our executor!
125         // executor.shutdown();
126
127         if (dataProvider != null) {
128             WriteTransaction tx = dataProvider.newWriteOnlyTransaction();
129             tx.delete(LogicalDatastoreType.OPERATIONAL, OPENSTACKEP_IID);
130             Futures.addCallback(tx.submit(), new FutureCallback<Void>() {
131                 @Override
132                 public void onSuccess(final Void result) {
133                     LOG.debug("Delete OS EP commit result: " + result);
134                 }
135
136                 @Override
137                 public void onFailure(final Throwable t) {
138                     LOG.error("Delete of OS EP failed", t);
139                 }
140             });
141         }
142     }
143
144     // ******************************************************************/
145     /**
146      * Construct an endpoint with the appropriate augmentations from the
147      * endpoint input. This can be overridden by a concrete implementation.
148      *
149      * @param input
150      *            the input object
151      */
152     protected EndpointBuilder buildEndpoint(RegisterEndpointInput input) {
153         return new EndpointBuilder(input);
154     }
155
156     /**
157      * Construct an L3 endpoint with the appropriate augmentations from the
158      * endpoint input. This can be overridden by a concrete implementation.
159      *
160      * @param input
161      *            the input object
162      */
163     protected EndpointL3Builder buildEndpointL3(RegisterEndpointInput input) {
164         return new EndpointL3Builder(input);
165     }
166
167     @Override
168     @Deprecated
169     public Future<RpcResult<Void>> unregisterEndpoint(
170             UnregisterEndpointInput input) {
171         WriteTransaction t = dataProvider.newWriteOnlyTransaction();
172         if (input.getL2() != null) {
173             for (L2 l2a : input.getL2()) {
174                 EndpointKey key = new EndpointKey(l2a.getL2Context(),
175                         l2a.getMacAddress());
176                 InstanceIdentifier<Endpoint> iid = InstanceIdentifier
177                         .builder(OpenstackEndpoints.class)
178                         .child(Endpoint.class, key).build();
179                 t.delete(LogicalDatastoreType.OPERATIONAL, iid);
180             }
181         }
182         if (input.getL3() != null) {
183             for (L3 l3addr : input.getL3()) {
184                 EndpointL3Key key3 = new EndpointL3Key(l3addr.getIpAddress(),
185                         l3addr.getL3Context());
186                 InstanceIdentifier<EndpointL3> iid_l3 = InstanceIdentifier
187                         .builder(OpenstackEndpoints.class)
188                         .child(EndpointL3.class, key3).build();
189                 t.delete(LogicalDatastoreType.OPERATIONAL, iid_l3);
190             }
191         }
192         unregisterStandardEndpoint(input);
193         ListenableFuture<Void> r = t.submit();
194         return Futures.transform(r, futureTrans, executor);
195     }
196
197     public Future<RpcResult<Void>> unregisterStandardEndpoint(
198             UnregisterEndpointInput input) {
199         WriteTransaction t = dataProvider.newWriteOnlyTransaction();
200         if (input.getL2() != null) {
201             for (L2 l2a : input.getL2()) {
202                 org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointKey key = new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointKey(
203                         l2a.getL2Context(), l2a.getMacAddress());
204                 if (existsL2Endpoint(key)) {
205                     InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint> iid = InstanceIdentifier
206                             .builder(
207                                     org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.Endpoints.class)
208                             .child(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint.class,
209                                     key).build();
210                     t.delete(LogicalDatastoreType.OPERATIONAL, iid);
211                 }
212
213             }
214         }
215         if (input.getL3() != null) {
216             for (L3 l3addr : input.getL3()) {
217                 org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Key key3 = new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Key(
218                         l3addr.getIpAddress(), l3addr.getL3Context());
219                 if (existsL3Endpoint(key3)) {
220                     InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3> iid_l3 = InstanceIdentifier
221                             .builder(Endpoints.class)
222                             .child(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3.class,
223                                     key3).build();
224                     t.delete(LogicalDatastoreType.OPERATIONAL, iid_l3);
225                 }
226             }
227         }
228         ListenableFuture<Void> r = t.submit();
229         return Futures.transform(r, futureTrans, executor);
230     }
231
232     private Boolean existsL2Endpoint(
233             org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointKey key) {
234         Boolean exists = false;
235         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint> iid = InstanceIdentifier
236                 .builder(Endpoints.class)
237                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint.class,
238                         key).build();
239
240         if (dataProvider != null) {
241             Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint> result;
242             try {
243                 result = dataProvider.newReadOnlyTransaction()
244                         .read(LogicalDatastoreType.OPERATIONAL, iid).get();
245                 if (result.isPresent()) {
246                     exists = true;
247                 }
248             } catch (InterruptedException | ExecutionException e) {
249                 LOG.error("Caught exception in existsL2Endpoint", e);
250             }
251         }
252         return exists;
253     }
254
255     private Boolean existsL3Endpoint(
256             org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Key keyL3) {
257         Boolean exists = false;
258         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3> iidL3 = InstanceIdentifier
259                 .builder(Endpoints.class)
260                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3.class,
261                         keyL3).build();
262         if (dataProvider != null) {
263             Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3> result;
264             try {
265                 result = dataProvider.newReadOnlyTransaction()
266                         .read(LogicalDatastoreType.OPERATIONAL, iidL3).get();
267                 if (result.isPresent()) {
268                     exists = true;
269                 }
270             } catch (InterruptedException | ExecutionException e) {
271                 LOG.error("Caught exception in existsL3Endpoint",e);
272             }
273         }
274         return exists;
275     }
276
277     @Override
278     @Deprecated
279     public Future<RpcResult<Void>> registerEndpoint(RegisterEndpointInput input) {
280         long timestamp = System.currentTimeMillis();
281
282         WriteTransaction t = dataProvider.newWriteOnlyTransaction();
283
284         if (input.getL2Context() != null && input.getMacAddress() != null) {
285             Endpoint ep = buildEndpoint(input).setTimestamp(timestamp).build();
286
287             EndpointKey key = new EndpointKey(ep.getL2Context(),
288                     ep.getMacAddress());
289             InstanceIdentifier<Endpoint> iid = InstanceIdentifier
290                     .builder(OpenstackEndpoints.class)
291                     .child(Endpoint.class, key).build();
292             t.put(LogicalDatastoreType.OPERATIONAL, iid, ep);
293             NodeInfo nodeInfo = mapNeutronPortToNodeInfo(ep.getNeutronPortId()
294                     .getValue());
295             if (nodeInfo.getNode() != null
296                     && nodeInfo.getNodeConnector() != null) {
297                 writeNewEp(translateEndpoint(ep, nodeInfo.getNodeConnector()
298                         .getId(), nodeInfo.getNode().getId()));
299             }
300         }
301         if (input.getL3Address() != null) {
302             for (L3Address l3addr : input.getL3Address()) {
303                 EndpointL3Key key3 = new EndpointL3Key(l3addr.getIpAddress(),
304                         l3addr.getL3Context());
305                 EndpointL3 ep3 = buildEndpointL3(input)
306                         .setIpAddress(key3.getIpAddress())
307                         .setL3Context(key3.getL3Context())
308                         .setTimestamp(timestamp).build();
309                 InstanceIdentifier<EndpointL3> iid_l3 = InstanceIdentifier
310                         .builder(OpenstackEndpoints.class)
311                         .child(EndpointL3.class, key3).build();
312                 t.put(LogicalDatastoreType.OPERATIONAL, iid_l3, ep3);
313                 NodeInfo nodeInfo = mapNeutronPortToNodeInfo(ep3
314                         .getNeutronPortId().toString());
315                 if (nodeInfo.getNode() != null
316                         && nodeInfo.getNodeConnector() != null) {
317                     writeNewEpL3(translateEndpointL3(ep3, nodeInfo
318                             .getNodeConnector().getId(), nodeInfo.getNode()
319                             .getId()));
320                 }
321             }
322         }
323         ListenableFuture<Void> r = t.submit();
324         return Futures.transform(r, futureTrans, executor);
325         // Now check for Nodes that match the neutron port id
326     }
327
328     // A wrapper class around node, noeConnector info so we can pass a final
329     // object inside OnSuccess anonymous inner class
330     private static class NodeInfo {
331         NodeConnector nodeConnector;
332         Node node;
333
334         private NodeInfo() {
335
336         }
337
338         private NodeInfo(NodeConnector nc, Node node) {
339             this.nodeConnector = nc;
340             this.node = node;
341         }
342
343         private Node getNode() {
344             return this.node;
345         }
346
347         private NodeConnector getNodeConnector() {
348             return this.nodeConnector;
349         }
350
351         public void setNodeConnector(NodeConnector nodeConnector) {
352             this.nodeConnector = nodeConnector;
353         }
354
355         public void setNode(Node node) {
356             this.node = node;
357         }
358     }
359
360     private NodeInfo mapNeutronPortToNodeInfo(final String neutronPortId) {
361         final NodeInfo nodeInfo = new NodeInfo();
362
363         if (dataProvider != null) {
364
365             ListenableFuture<Optional<Nodes>> future = dataProvider
366                     .newReadOnlyTransaction().read(
367                             LogicalDatastoreType.OPERATIONAL, nodesIid);
368
369             Futures.addCallback(future, new FutureCallback<Optional<Nodes>>() {
370                 @Override
371                 public void onSuccess(Optional<Nodes> result) {
372                     if (result.isPresent()) {
373                         Nodes nodes = result.get();
374                         for (Node node : nodes.getNode()) {
375                             if (node.getNodeConnector() != null) {
376                                 for (NodeConnector nc : node.getNodeConnector()) {
377                                     FlowCapableNodeConnector fcnc = nc
378                                             .getAugmentation(FlowCapableNodeConnector.class);
379                                     if (fcnc.getName().equals(neutronPortId)) {
380                                         nodeInfo.setNode(node);
381                                         nodeInfo.setNodeConnector(nc);
382                                     }
383                                 }
384                             }
385                         }
386
387                     }
388                 }
389
390                 @Override
391                 public void onFailure(Throwable t) {
392                     LOG.error("Count not read switch information", t);
393                 }
394             });
395         }
396         return nodeInfo;
397     }
398
399     private Future<RpcResult<Void>> writeNewEp(
400             org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint ep) {
401         WriteTransaction t = dataProvider.newWriteOnlyTransaction();
402         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint> iid = InstanceIdentifier
403                 .builder(
404                         org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.Endpoints.class)
405                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint.class,
406                         ep.getKey()).build();
407         t.put(LogicalDatastoreType.OPERATIONAL, iid, ep);
408         ListenableFuture<Void> r = t.submit();
409         return Futures.transform(r, futureTrans, executor);
410
411     }
412
413     private Future<RpcResult<Void>> writeNewEpL3(
414             org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3 ep) {
415         WriteTransaction t = dataProvider.newWriteOnlyTransaction();
416         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3> iid = InstanceIdentifier
417                 .builder(
418                         org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.Endpoints.class)
419                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3.class,
420                         ep.getKey()).build();
421         t.put(LogicalDatastoreType.OPERATIONAL, iid, ep);
422         ListenableFuture<Void> r = t.submit();
423         return Futures.transform(r, futureTrans, executor);
424
425     }
426
427     private boolean validEp(Endpoint endpoint) {
428         return (endpoint != null && endpoint.getTenant() != null
429                 && endpoint.getEndpointGroup() != null
430                 && endpoint.getL2Context() != null && endpoint.getMacAddress() != null);
431     }
432
433     private org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint translateEndpoint(
434             Endpoint ep, NodeConnectorId nodeConnectorId, NodeId nodeId) {
435         OfOverlayContextBuilder ofOverlayAugmentation = new OfOverlayContextBuilder();
436         ofOverlayAugmentation.setNodeId(nodeId);
437         ofOverlayAugmentation.setNodeConnectorId(nodeConnectorId);
438         org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder newEpBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder();
439         newEpBuilder.addAugmentation(OfOverlayContext.class,
440                 ofOverlayAugmentation.build());
441         newEpBuilder.setCondition(ep.getCondition());
442         newEpBuilder.setEndpointGroup(ep.getEndpointGroup());
443         newEpBuilder.setL2Context(ep.getL2Context());
444         newEpBuilder.setMacAddress(ep.getMacAddress());
445         org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointKey newEpKey = new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointKey(
446                 ep.getL2Context(), ep.getMacAddress());
447         newEpBuilder.setKey(newEpKey);
448         List<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address> newL3AddressList = new ArrayList<>();
449         if (ep.getL3Address() != null) {
450             for (L3Address l3 : ep.getL3Address()) {
451                 LOG.debug(l3.toString());
452                 org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder newL3AddressBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder();
453                 newL3AddressBuilder.setIpAddress(l3.getIpAddress());
454                 newL3AddressBuilder.setL3Context(l3.getL3Context());
455                 newL3AddressList.add(newL3AddressBuilder.build());
456             }
457         }
458         newEpBuilder.setL3Address(newL3AddressList);
459         newEpBuilder.setTenant(ep.getTenant());
460         newEpBuilder.setTimestamp(ep.getTimestamp());
461         return newEpBuilder.build();
462     }
463
464     private org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3 translateEndpointL3(
465             EndpointL3 ep, NodeConnectorId nodeConnectorId, NodeId nodeId) {
466         org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Builder newEpL3Builder = new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Builder();
467
468         newEpL3Builder.setCondition(ep.getCondition());
469         newEpL3Builder.setIpAddress(ep.getIpAddress());
470         newEpL3Builder.setL3Context(ep.getL3Context());
471         newEpL3Builder.setEndpointGroup(ep.getEndpointGroup());
472         newEpL3Builder.setL2Context(ep.getL2Context());
473         newEpL3Builder.setMacAddress(ep.getMacAddress());
474
475         org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Key newEpL3Key = new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Key(
476                 ep.getIpAddress(), ep.getL3Context());
477         newEpL3Builder.setKey(newEpL3Key);
478         List<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address> newL3AddressList = new ArrayList<>();
479         for (L3Address l3 : ep.getL3Address()) {
480             LOG.debug(l3.toString());
481             org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder newL3AddressBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder();
482             newL3AddressBuilder.setIpAddress(l3.getIpAddress());
483             newL3AddressBuilder.setL3Context(l3.getL3Context());
484             newL3AddressList.add(newL3AddressBuilder.build());
485         }
486         newEpL3Builder.setL3Address(newL3AddressList);
487         newEpL3Builder.setTenant(ep.getTenant());
488         newEpL3Builder.setTimestamp(ep.getTimestamp());
489         return newEpL3Builder.build();
490     }
491
492     private void updateOfOverlayEndpoint(final String neutronPortId,
493             final NodeConnectorId nodeConnectorId, final NodeId nodeId) {
494
495         if (dataProvider != null) {
496             InstanceIdentifier<OpenstackEndpoints> iid = InstanceIdentifier
497                     .builder(OpenstackEndpoints.class).build();
498             ListenableFuture<Optional<OpenstackEndpoints>> future = dataProvider
499                     .newReadOnlyTransaction().read(
500                             LogicalDatastoreType.OPERATIONAL, iid);
501             Futures.addCallback(future,
502                     new FutureCallback<Optional<OpenstackEndpoints>>() {
503                         @Override
504                         public void onSuccess(
505                                 Optional<OpenstackEndpoints> result) {
506                             if (result.isPresent()) {
507                                 OpenstackEndpoints openstackEndpoints = result
508                                         .get();
509                                 if (openstackEndpoints.getEndpoint() != null) {
510                                     for (Endpoint ep : openstackEndpoints
511                                             .getEndpoint()) {
512                                         if (validEp(ep)
513                                                 && ep.getNeutronPortId()
514                                                         .getValue()
515                                                         .equals(neutronPortId)) {
516                                             LOG.debug("Match: " + ep.toString());
517                                             org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint newEp = translateEndpoint(
518                                                     ep, nodeConnectorId, nodeId);
519                                             writeNewEp(newEp);
520                                             LOG.debug(newEp.toString());
521                                         }
522                                     }
523                                 }
524                                 if (openstackEndpoints.getEndpointL3() != null) {
525                                     for (EndpointL3 ep : openstackEndpoints
526                                             .getEndpointL3()) {
527                                         if (ep.getNeutronPortId().getValue()
528                                                 .equals(neutronPortId)) {
529                                             LOG.debug("L3 Match: "
530                                                     + ep.toString());
531                                             org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3 newEpL3 = translateEndpointL3(
532                                                     ep, nodeConnectorId, nodeId);
533                                             writeNewEpL3(newEpL3);
534                                             LOG.debug(newEpL3.toString());
535                                         }
536                                     }
537                                 }
538                             }
539                         }
540
541                         @Override
542                         public void onFailure(Throwable t) {
543                             LOG.error("Count not read switch information", t);
544                         }
545                     });
546         }
547     }
548
549     private class NodesListener implements DataChangeListener {
550         @Override
551         public void onDataChanged(
552                 AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
553             for (DataObject dao : change.getCreatedData().values()) {
554                 if (!(dao instanceof Node))
555                     continue;
556                 Node node = (Node) dao;
557                 if (node.getNodeConnector() != null) {
558                     for (NodeConnector nc : node.getNodeConnector()) {
559                         FlowCapableNodeConnector fcnc = nc
560                                 .getAugmentation(FlowCapableNodeConnector.class);
561                         if (fcnc.getName().matches(
562                                 "tap[a-f,0-9]{8}-[a-f,0-9]{2}")) {
563                             LOG.debug("Created Tap:" + fcnc.getName() + ": "
564                                     + nc.getId() + " : " + node.getId());
565                             updateOfOverlayEndpoint(fcnc.getName(), nc.getId(),
566                                     node.getId());
567                         }
568                     }
569                 }
570             }
571             for (DataObject dao : change.getUpdatedData().values()) {
572                 if (!(dao instanceof Node))
573                     continue;
574                 Node node = (Node) dao;
575                 if (node.getNodeConnector() != null) {
576                     for (NodeConnector nc : node.getNodeConnector()) {
577                         FlowCapableNodeConnector fcnc = nc
578                                 .getAugmentation(FlowCapableNodeConnector.class);
579                         if (fcnc.getName().matches(
580                                 "tap[a-f,0-9]{8}-[a-f,0-9]{2}")) {
581                             LOG.debug("Updated Tap:" + fcnc.getName() + ": "
582                                     + nc.getId() + " : " + node.getId());
583                             updateOfOverlayEndpoint(fcnc.getName(), nc.getId(),
584                                     node.getId());
585                         }
586                     }
587                 }
588             }
589         }
590     }
591
592     Function<Void, RpcResult<Void>> futureTrans = new Function<Void, RpcResult<Void>>() {
593         @Override
594         public RpcResult<Void> apply(Void input) {
595             return RpcResultBuilder.<Void> success().build();
596         }
597     };
598 }