Merge "Move utility function to common place."
[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      * @param timestamp
152      *            the current timestamp
153      */
154     protected EndpointBuilder buildEndpoint(RegisterEndpointInput input) {
155         return new EndpointBuilder(input);
156     }
157
158     /**
159      * Construct an L3 endpoint with the appropriate augmentations from the
160      * endpoint input. This can be overridden by a concrete implementation.
161      *
162      * @param input
163      *            the input object
164      * @param timestamp
165      *            the current timestamp
166      */
167     protected EndpointL3Builder buildEndpointL3(RegisterEndpointInput input) {
168         return new EndpointL3Builder(input);
169     }
170
171     @Override
172     @Deprecated
173     public Future<RpcResult<Void>> unregisterEndpoint(
174             UnregisterEndpointInput input) {
175         WriteTransaction t = dataProvider.newWriteOnlyTransaction();
176         if (input.getL2() != null) {
177             for (L2 l2a : input.getL2()) {
178                 EndpointKey key = new EndpointKey(l2a.getL2Context(),
179                         l2a.getMacAddress());
180                 InstanceIdentifier<Endpoint> iid = InstanceIdentifier
181                         .builder(OpenstackEndpoints.class)
182                         .child(Endpoint.class, key).build();
183                 t.delete(LogicalDatastoreType.OPERATIONAL, iid);
184             }
185         }
186         if (input.getL3() != null) {
187             for (L3 l3addr : input.getL3()) {
188                 EndpointL3Key key3 = new EndpointL3Key(l3addr.getIpAddress(),
189                         l3addr.getL3Context());
190                 InstanceIdentifier<EndpointL3> iid_l3 = InstanceIdentifier
191                         .builder(OpenstackEndpoints.class)
192                         .child(EndpointL3.class, key3).build();
193                 t.delete(LogicalDatastoreType.OPERATIONAL, iid_l3);
194             }
195         }
196         unregisterStandardEndpoint(input);
197         ListenableFuture<Void> r = t.submit();
198         return Futures.transform(r, futureTrans, executor);
199     }
200
201     public Future<RpcResult<Void>> unregisterStandardEndpoint(
202             UnregisterEndpointInput input) {
203         WriteTransaction t = dataProvider.newWriteOnlyTransaction();
204         if (input.getL2() != null) {
205             for (L2 l2a : input.getL2()) {
206                 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(
207                         l2a.getL2Context(), l2a.getMacAddress());
208                 if (existsL2Endpoint(key)) {
209                     InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint> iid = InstanceIdentifier
210                             .builder(
211                                     org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.Endpoints.class)
212                             .child(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint.class,
213                                     key).build();
214                     t.delete(LogicalDatastoreType.OPERATIONAL, iid);
215                 }
216
217             }
218         }
219         if (input.getL3() != null) {
220             for (L3 l3addr : input.getL3()) {
221                 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(
222                         l3addr.getIpAddress(), l3addr.getL3Context());
223                 if (existsL3Endpoint(key3)) {
224                     InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3> iid_l3 = InstanceIdentifier
225                             .builder(Endpoints.class)
226                             .child(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3.class,
227                                     key3).build();
228                     t.delete(LogicalDatastoreType.OPERATIONAL, iid_l3);
229                 }
230             }
231         }
232         ListenableFuture<Void> r = t.submit();
233         return Futures.transform(r, futureTrans, executor);
234     }
235
236     private Boolean existsL2Endpoint(
237             org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointKey key) {
238         Boolean exists = false;
239         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint> iid = InstanceIdentifier
240                 .builder(Endpoints.class)
241                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint.class,
242                         key).build();
243
244         if (dataProvider != null) {
245             Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint> result;
246             try {
247                 result = dataProvider.newReadOnlyTransaction()
248                         .read(LogicalDatastoreType.OPERATIONAL, iid).get();
249                 if (result.isPresent()) {
250                     exists = true;
251                 }
252             } catch (InterruptedException | ExecutionException e) {
253                 LOG.error("Caught exception in existsL2Endpoint", e);
254             }
255         }
256         return exists;
257     }
258
259     private Boolean existsL3Endpoint(
260             org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Key keyL3) {
261         Boolean exists = false;
262         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3> iidL3 = InstanceIdentifier
263                 .builder(Endpoints.class)
264                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3.class,
265                         keyL3).build();
266         if (dataProvider != null) {
267             Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3> result;
268             try {
269                 result = dataProvider.newReadOnlyTransaction()
270                         .read(LogicalDatastoreType.OPERATIONAL, iidL3).get();
271                 if (result.isPresent()) {
272                     exists = true;
273                 }
274             } catch (InterruptedException | ExecutionException e) {
275                 LOG.error("Caught exception in existsL3Endpoint",e);
276             }
277         }
278         return exists;
279     }
280
281     @Override
282     @Deprecated
283     public Future<RpcResult<Void>> registerEndpoint(RegisterEndpointInput input) {
284         long timestamp = System.currentTimeMillis();
285
286         WriteTransaction t = dataProvider.newWriteOnlyTransaction();
287
288         if (input.getL2Context() != null && input.getMacAddress() != null) {
289             Endpoint ep = buildEndpoint(input).setTimestamp(timestamp).build();
290
291             EndpointKey key = new EndpointKey(ep.getL2Context(),
292                     ep.getMacAddress());
293             InstanceIdentifier<Endpoint> iid = InstanceIdentifier
294                     .builder(OpenstackEndpoints.class)
295                     .child(Endpoint.class, key).build();
296             t.put(LogicalDatastoreType.OPERATIONAL, iid, ep);
297             NodeInfo nodeInfo = mapNeutronPortToNodeInfo(ep.getNeutronPortId()
298                     .getValue());
299             if (nodeInfo.getNode() != null
300                     && nodeInfo.getNodeConnector() != null) {
301                 writeNewEp(translateEndpoint(ep, nodeInfo.getNodeConnector()
302                         .getId(), nodeInfo.getNode().getId()));
303             }
304         }
305         if (input.getL3Address() != null) {
306             for (L3Address l3addr : input.getL3Address()) {
307                 EndpointL3Key key3 = new EndpointL3Key(l3addr.getIpAddress(),
308                         l3addr.getL3Context());
309                 EndpointL3 ep3 = buildEndpointL3(input)
310                         .setIpAddress(key3.getIpAddress())
311                         .setL3Context(key3.getL3Context())
312                         .setTimestamp(timestamp).build();
313                 InstanceIdentifier<EndpointL3> iid_l3 = InstanceIdentifier
314                         .builder(OpenstackEndpoints.class)
315                         .child(EndpointL3.class, key3).build();
316                 t.put(LogicalDatastoreType.OPERATIONAL, iid_l3, ep3);
317                 NodeInfo nodeInfo = mapNeutronPortToNodeInfo(ep3
318                         .getNeutronPortId().toString());
319                 if (nodeInfo.getNode() != null
320                         && nodeInfo.getNodeConnector() != null) {
321                     writeNewEpL3(translateEndpointL3(ep3, nodeInfo
322                             .getNodeConnector().getId(), nodeInfo.getNode()
323                             .getId()));
324                 }
325             }
326         }
327         ListenableFuture<Void> r = t.submit();
328         return Futures.transform(r, futureTrans, executor);
329         // Now check for Nodes that match the neutron port id
330     }
331
332     // A wrapper class around node, noeConnector info so we can pass a final
333     // object inside OnSuccess anonymous inner class
334     private static class NodeInfo {
335         NodeConnector nodeConnector;
336         Node node;
337
338         private NodeInfo() {
339
340         }
341
342         private NodeInfo(NodeConnector nc, Node node) {
343             this.nodeConnector = nc;
344             this.node = node;
345         }
346
347         private Node getNode() {
348             return this.node;
349         }
350
351         private NodeConnector getNodeConnector() {
352             return this.nodeConnector;
353         }
354
355         public void setNodeConnector(NodeConnector nodeConnector) {
356             this.nodeConnector = nodeConnector;
357         }
358
359         public void setNode(Node node) {
360             this.node = node;
361         }
362     }
363
364     private NodeInfo mapNeutronPortToNodeInfo(final String neutronPortId) {
365         final NodeInfo nodeInfo = new NodeInfo();
366
367         if (dataProvider != null) {
368
369             ListenableFuture<Optional<Nodes>> future = dataProvider
370                     .newReadOnlyTransaction().read(
371                             LogicalDatastoreType.OPERATIONAL, nodesIid);
372
373             Futures.addCallback(future, new FutureCallback<Optional<Nodes>>() {
374                 @Override
375                 public void onSuccess(Optional<Nodes> result) {
376                     if (result.isPresent()) {
377                         Nodes nodes = result.get();
378                         for (Node node : nodes.getNode()) {
379                             if (node.getNodeConnector() != null) {
380                                 for (NodeConnector nc : node.getNodeConnector()) {
381                                     FlowCapableNodeConnector fcnc = nc
382                                             .getAugmentation(FlowCapableNodeConnector.class);
383                                     if (fcnc.getName().equals(neutronPortId)) {
384                                         nodeInfo.setNode(node);
385                                         nodeInfo.setNodeConnector(nc);
386                                     }
387                                 }
388                             }
389                         }
390
391                     }
392                 }
393
394                 @Override
395                 public void onFailure(Throwable t) {
396                     LOG.error("Count not read switch information", t);
397                 }
398             });
399         }
400         return nodeInfo;
401     }
402
403     private Future<RpcResult<Void>> writeNewEp(
404             org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint ep) {
405         WriteTransaction t = dataProvider.newWriteOnlyTransaction();
406         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint> iid = InstanceIdentifier
407                 .builder(
408                         org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.Endpoints.class)
409                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint.class,
410                         ep.getKey()).build();
411         t.put(LogicalDatastoreType.OPERATIONAL, iid, ep);
412         ListenableFuture<Void> r = t.submit();
413         return Futures.transform(r, futureTrans, executor);
414
415     }
416
417     private Future<RpcResult<Void>> writeNewEpL3(
418             org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3 ep) {
419         WriteTransaction t = dataProvider.newWriteOnlyTransaction();
420         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3> iid = InstanceIdentifier
421                 .builder(
422                         org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.Endpoints.class)
423                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3.class,
424                         ep.getKey()).build();
425         t.put(LogicalDatastoreType.OPERATIONAL, iid, ep);
426         ListenableFuture<Void> r = t.submit();
427         return Futures.transform(r, futureTrans, executor);
428
429     }
430
431     private boolean validEp(Endpoint endpoint) {
432         return (endpoint != null && endpoint.getTenant() != null
433                 && endpoint.getEndpointGroup() != null
434                 && endpoint.getL2Context() != null && endpoint.getMacAddress() != null);
435     }
436
437     private org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint translateEndpoint(
438             Endpoint ep, NodeConnectorId nodeConnectorId, NodeId nodeId) {
439         OfOverlayContextBuilder ofOverlayAugmentation = new OfOverlayContextBuilder();
440         ofOverlayAugmentation.setNodeId(nodeId);
441         ofOverlayAugmentation.setNodeConnectorId(nodeConnectorId);
442         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();
443         newEpBuilder.addAugmentation(OfOverlayContext.class,
444                 ofOverlayAugmentation.build());
445         newEpBuilder.setCondition(ep.getCondition());
446         newEpBuilder.setEndpointGroup(ep.getEndpointGroup());
447         newEpBuilder.setL2Context(ep.getL2Context());
448         newEpBuilder.setMacAddress(ep.getMacAddress());
449         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(
450                 ep.getL2Context(), ep.getMacAddress());
451         newEpBuilder.setKey(newEpKey);
452         List<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address> newL3AddressList = new ArrayList<>();
453         if (ep.getL3Address() != null) {
454             for (L3Address l3 : ep.getL3Address()) {
455                 LOG.debug(l3.toString());
456                 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();
457                 newL3AddressBuilder.setIpAddress(l3.getIpAddress());
458                 newL3AddressBuilder.setL3Context(l3.getL3Context());
459                 newL3AddressList.add(newL3AddressBuilder.build());
460             }
461         }
462         newEpBuilder.setL3Address(newL3AddressList);
463         newEpBuilder.setTenant(ep.getTenant());
464         newEpBuilder.setTimestamp(ep.getTimestamp());
465         return newEpBuilder.build();
466     }
467
468     private org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3 translateEndpointL3(
469             EndpointL3 ep, NodeConnectorId nodeConnectorId, NodeId nodeId) {
470         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();
471
472         newEpL3Builder.setCondition(ep.getCondition());
473         newEpL3Builder.setIpAddress(ep.getIpAddress());
474         newEpL3Builder.setL3Context(ep.getL3Context());
475         newEpL3Builder.setEndpointGroup(ep.getEndpointGroup());
476         newEpL3Builder.setL2Context(ep.getL2Context());
477         newEpL3Builder.setMacAddress(ep.getMacAddress());
478
479         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(
480                 ep.getIpAddress(), ep.getL3Context());
481         newEpL3Builder.setKey(newEpL3Key);
482         List<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address> newL3AddressList = new ArrayList<>();
483         for (L3Address l3 : ep.getL3Address()) {
484             LOG.debug(l3.toString());
485             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();
486             newL3AddressBuilder.setIpAddress(l3.getIpAddress());
487             newL3AddressBuilder.setL3Context(l3.getL3Context());
488             newL3AddressList.add(newL3AddressBuilder.build());
489         }
490         newEpL3Builder.setL3Address(newL3AddressList);
491         newEpL3Builder.setTenant(ep.getTenant());
492         newEpL3Builder.setTimestamp(ep.getTimestamp());
493         return newEpL3Builder.build();
494     }
495
496     private void updateOfOverlayEndpoint(final String neutronPortId,
497             final NodeConnectorId nodeConnectorId, final NodeId nodeId) {
498
499         if (dataProvider != null) {
500             InstanceIdentifier<OpenstackEndpoints> iid = InstanceIdentifier
501                     .builder(OpenstackEndpoints.class).build();
502             ListenableFuture<Optional<OpenstackEndpoints>> future = dataProvider
503                     .newReadOnlyTransaction().read(
504                             LogicalDatastoreType.OPERATIONAL, iid);
505             Futures.addCallback(future,
506                     new FutureCallback<Optional<OpenstackEndpoints>>() {
507                         @Override
508                         public void onSuccess(
509                                 Optional<OpenstackEndpoints> result) {
510                             if (result.isPresent()) {
511                                 OpenstackEndpoints openstackEndpoints = result
512                                         .get();
513                                 if (openstackEndpoints.getEndpoint() != null) {
514                                     for (Endpoint ep : openstackEndpoints
515                                             .getEndpoint()) {
516                                         if (validEp(ep)
517                                                 && ep.getNeutronPortId()
518                                                         .getValue()
519                                                         .equals(neutronPortId)) {
520                                             LOG.debug("Match: " + ep.toString());
521                                             org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint newEp = translateEndpoint(
522                                                     ep, nodeConnectorId, nodeId);
523                                             writeNewEp(newEp);
524                                             LOG.debug(newEp.toString());
525                                         }
526                                     }
527                                 }
528                                 if (openstackEndpoints.getEndpointL3() != null) {
529                                     for (EndpointL3 ep : openstackEndpoints
530                                             .getEndpointL3()) {
531                                         if (ep.getNeutronPortId().getValue()
532                                                 .equals(neutronPortId)) {
533                                             LOG.debug("L3 Match: "
534                                                     + ep.toString());
535                                             org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3 newEpL3 = translateEndpointL3(
536                                                     ep, nodeConnectorId, nodeId);
537                                             writeNewEpL3(newEpL3);
538                                             LOG.debug(newEpL3.toString());
539                                         }
540                                     }
541                                 }
542                             }
543                         }
544
545                         @Override
546                         public void onFailure(Throwable t) {
547                             LOG.error("Count not read switch information", t);
548                         }
549                     });
550         }
551     }
552
553     private class NodesListener implements DataChangeListener {
554         @Override
555         public void onDataChanged(
556                 AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
557             for (DataObject dao : change.getCreatedData().values()) {
558                 if (!(dao instanceof Node))
559                     continue;
560                 Node node = (Node) dao;
561                 if (node.getNodeConnector() != null) {
562                     for (NodeConnector nc : node.getNodeConnector()) {
563                         FlowCapableNodeConnector fcnc = nc
564                                 .getAugmentation(FlowCapableNodeConnector.class);
565                         if (fcnc.getName().matches(
566                                 "tap[a-f,0-9]{8}-[a-f,0-9]{2}")) {
567                             LOG.debug("Created Tap:" + fcnc.getName() + ": "
568                                     + nc.getId() + " : " + node.getId());
569                             updateOfOverlayEndpoint(fcnc.getName(), nc.getId(),
570                                     node.getId());
571                         }
572                     }
573                 }
574             }
575             for (DataObject dao : change.getUpdatedData().values()) {
576                 if (!(dao instanceof Node))
577                     continue;
578                 Node node = (Node) dao;
579                 if (node.getNodeConnector() != null) {
580                     for (NodeConnector nc : node.getNodeConnector()) {
581                         FlowCapableNodeConnector fcnc = nc
582                                 .getAugmentation(FlowCapableNodeConnector.class);
583                         if (fcnc.getName().matches(
584                                 "tap[a-f,0-9]{8}-[a-f,0-9]{2}")) {
585                             LOG.debug("Updated Tap:" + fcnc.getName() + ": "
586                                     + nc.getId() + " : " + node.getId());
587                             updateOfOverlayEndpoint(fcnc.getName(), nc.getId(),
588                                     node.getId());
589                         }
590                     }
591                 }
592             }
593         }
594     }
595
596     Function<Void, RpcResult<Void>> futureTrans = new Function<Void, RpcResult<Void>>() {
597         @Override
598         public RpcResult<Void> apply(Void input) {
599             return RpcResultBuilder.<Void> success().build();
600         }
601     };
602 }