2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.groupbasedpolicy.renderer.vpp.listener;
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;
16 import javax.annotation.Nonnull;
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;
32 public class VppEndpointListener extends DataTreeChangeHandler<VppEndpoint> {
34 private static final Logger LOG = LoggerFactory.getLogger(VppEndpointListener.class);
35 private Table<String, String, VppEndpointConfEvent> pendingEndpointsTable = HashBasedTable.create();
36 private EventBus eventBus;
38 public VppEndpointListener(DataBroker dataProvider, EventBus eventBus) {
40 this.eventBus = Preconditions.checkNotNull(eventBus);
41 registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
42 InstanceIdentifier.builder(Config.class).child(VppEndpoint.class).build()));
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());
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()));
70 LOG.info("onDelete -> Caching pending deleted endpoint {}", rootNode.getDataBefore());
71 pendingEndpointsTable.put(vppEndpointBefore.getVppNodeId().getValue(), intfName, new VppEndpointConfEvent(rootIdentifier, rootNode.getDataBefore(), rootNode.getDataAfter()));
74 deleteVppEndpoint(new VppEndpointConfEvent(rootIdentifier, rootNode.getDataBefore(), rootNode.getDataAfter()));
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);
86 private void deleteVppEndpoint(VppEndpointConfEvent vppEpConfEvent) {
87 eventBus.post(vppEpConfEvent);
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);
96 boolean canRemove = (vppEndpointConfEvent != null && !portIsBusy(vppEndpointConfEvent.getBefore().get()));
97 LOG.trace("flushPendingVppEndpoint: can remove {} - > VppEp: {}", canRemove, vppEndpointConfEvent);
99 LOG.trace("flushPendingVppEndpoint: hostName: {} for interface: {}", hostName, intfName);
100 deleteVppEndpoint(vppEndpointConfEvent);
101 pendingEndpointsTable.remove(hostName, intfName);
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);