Cleanup of Lisp in VPP renderer
[groupbasedpolicy.git] / renderers / vpp / src / main / java / org / opendaylight / groupbasedpolicy / renderer / vpp / listener / VppEndpointListener.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.groupbasedpolicy.renderer.vpp.listener;
10
11 import com.google.common.base.Preconditions;
12 import com.google.common.collect.HashBasedTable;
13 import com.google.common.collect.Table;
14 import com.google.common.eventbus.EventBus;
15
16 import javax.annotation.Nonnull;
17
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
20 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22 import org.opendaylight.groupbasedpolicy.renderer.vpp.config.ConfigUtil;
23 import org.opendaylight.groupbasedpolicy.renderer.vpp.event.VppEndpointConfEvent;
24 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.HostRelatedInfoContainer;
25 import org.opendaylight.groupbasedpolicy.util.DataTreeChangeHandler;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.Config;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;
28 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 public class VppEndpointListener extends DataTreeChangeHandler<VppEndpoint> {
33
34     private static final Logger LOG = LoggerFactory.getLogger(VppEndpointListener.class);
35     private Table<String, String, VppEndpointConfEvent> pendingEndpointsTable = HashBasedTable.create();
36     private EventBus eventBus;
37
38     public VppEndpointListener(DataBroker dataProvider, EventBus eventBus) {
39         super(dataProvider);
40         this.eventBus = Preconditions.checkNotNull(eventBus);
41         registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
42                 InstanceIdentifier.builder(Config.class).child(VppEndpoint.class).build()));
43     }
44
45     @Override
46     protected void onWrite(DataObjectModification<VppEndpoint> rootNode,
47             InstanceIdentifier<VppEndpoint> rootIdentifier) {
48         VppEndpointConfEvent event =
49                 new VppEndpointConfEvent(rootIdentifier, rootNode.getDataBefore(), rootNode.getDataAfter());
50         LOG.debug("Dispatching event on write: {}", event.getClass());
51         eventBus.post(event);
52     }
53
54     @Override
55     protected void onDelete(DataObjectModification<VppEndpoint> rootNode,
56         InstanceIdentifier<VppEndpoint> rootIdentifier) {
57         if (ConfigUtil.getInstance().isL3FlatEnabled()) {
58             VppEndpoint vppEndpointBefore = rootNode.getDataBefore();
59             Preconditions.checkNotNull(vppEndpointBefore, "VppEndpoint cannot be null on delete operation.");
60             LOG.trace("onDelete -> Vppendpoint deleted: {}", vppEndpointBefore);
61             Preconditions.checkArgument(vppEndpointBefore.getVppNodeId() != null);
62             Preconditions.checkArgument(vppEndpointBefore.getVppInterfaceName() != null);
63             String intfName = rootNode.getDataBefore().getVppInterfaceName();
64             LOG.info("onDelete -> Checking pending endpoint to delete {}", pendingEndpointsTable.get(vppEndpointBefore.getVppNodeId().getValue(), intfName));
65             if(!portIsBusy(rootNode.getDataBefore())) {
66                 LOG.info("onDelete -> Endpoint is not busy, deleting {}", vppEndpointBefore);
67                 deleteVppEndpoint(new VppEndpointConfEvent(rootIdentifier, rootNode.getDataBefore(), rootNode.getDataAfter()));
68             }
69             else {
70                 LOG.info("onDelete -> Caching pending deleted endpoint {}", rootNode.getDataBefore());
71                 pendingEndpointsTable.put(vppEndpointBefore.getVppNodeId().getValue(), intfName, new VppEndpointConfEvent(rootIdentifier, rootNode.getDataBefore(), rootNode.getDataAfter()));
72             }
73         } else {
74             deleteVppEndpoint(new VppEndpointConfEvent(rootIdentifier, rootNode.getDataBefore(), rootNode.getDataAfter()));
75         }
76     }
77
78     private boolean portIsBusy(VppEndpoint vppEndpoint) {
79         HostRelatedInfoContainer hrc = HostRelatedInfoContainer.getInstance();
80         boolean intfcIsInUse =
81                 hrc.intfcIsBusy(vppEndpoint.getVppNodeId().getValue(), vppEndpoint.getVppInterfaceName());
82         LOG.trace("onDelete -> isPortInUse: {} for vppEp: {}", intfcIsInUse, vppEndpoint);
83         return intfcIsInUse;
84     }
85
86     private void deleteVppEndpoint(VppEndpointConfEvent vppEpConfEvent) {
87         eventBus.post(vppEpConfEvent);
88     }
89
90     public void flushPendingVppEndpoint(@Nonnull String hostName,@Nonnull String intfName) {
91         Preconditions.checkNotNull(hostName);
92         Preconditions.checkNotNull(intfName);
93         LOG.trace("flushPendingVppEndpoint: hostname: {}, intfName: {}", hostName, intfName);
94         VppEndpointConfEvent vppEndpointConfEvent = pendingEndpointsTable.get(hostName, intfName);
95
96         boolean canRemove = (vppEndpointConfEvent != null && !portIsBusy(vppEndpointConfEvent.getBefore().get()));
97         LOG.trace("flushPendingVppEndpoint: can remove {} - > VppEp: {}", canRemove, vppEndpointConfEvent);
98         if (canRemove) {
99             LOG.trace("flushPendingVppEndpoint: hostName: {} for interface: {}", hostName, intfName);
100             deleteVppEndpoint(vppEndpointConfEvent);
101             pendingEndpointsTable.remove(hostName, intfName);
102         }
103     }
104
105     @Override
106     protected void onSubtreeModified(DataObjectModification<VppEndpoint> rootNode,
107             InstanceIdentifier<VppEndpoint> rootIdentifier) {
108         VppEndpointConfEvent event =
109                 new VppEndpointConfEvent(rootIdentifier, rootNode.getDataBefore(), rootNode.getDataAfter());
110         LOG.debug("Dispatching event on subtree modified: {}", event.getClass());
111         eventBus.post(event);
112     }
113
114 }