Merge "Add back the proper NetvirtSfc flows"
[ovsdb.git] / openstack / net-virt-sfc / impl / src / main / java / org / opendaylight / ovsdb / openstack / netvirt / sfc / NetvirtSfcAclListener.java
1 /*
2  * Copyright © 2015 Dell, 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.ovsdb.openstack.netvirt.sfc;
10
11 import com.google.common.base.Preconditions;
12 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
13 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
14 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
15 import org.opendaylight.ovsdb.openstack.netvirt.sfc.openflow13.INetvirtSfcOF13Provider;
16 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.AccessLists;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.Acl;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.AclKey;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.AccessListEntries;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.Ace;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.AceKey;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.Classifiers;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.Classifier;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.bridges.Bridge;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.sffs.Sff;
27 import org.opendaylight.yangtools.concepts.ListenerRegistration;
28 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 /**
33  * Data tree listener for AccessList.
34  */
35 public class NetvirtSfcAclListener extends AbstractDataTreeListener<Acl> {
36     private static final Logger LOG = LoggerFactory.getLogger(NetvirtSfcAclListener.class);
37     private ListenerRegistration<NetvirtSfcAclListener> listenerRegistration;
38     private MdsalUtils dbutils;
39
40     /**
41      * {@link NetvirtSfcAclListener} constructor.
42      * @param provider OpenFlow 1.3 Provider
43      * @param db MdSal {@link DataBroker}
44      */
45     public NetvirtSfcAclListener(final INetvirtSfcOF13Provider provider, final DataBroker db) {
46         super(provider, Acl.class);
47         Preconditions.checkNotNull(db, "DataBroker can not be null!");
48
49         dbutils = new MdsalUtils(db);
50         registrationListener(db);
51     }
52
53     private void registrationListener(final DataBroker db) {
54         final DataTreeIdentifier<Acl> treeId =
55                 new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, getIetfAclIid());
56         try {
57             LOG.info("Registering Data Change Listener for NetvirtSfc AccesList configuration.");
58             listenerRegistration = db.registerDataTreeChangeListener(treeId, this);
59         } catch (final Exception e) {
60             LOG.warn("Netvirt AccesList DataChange listener registration fail!");
61             LOG.debug("Netvirt AccesList DataChange listener registration fail!", e);
62             throw new IllegalStateException("NetvirtSfcAccesListListener startup fail! System needs restart.", e);
63         }
64     }
65
66     @Override
67     public void close() {
68         if (listenerRegistration != null) {
69             try {
70                 listenerRegistration.close();
71             } catch (final Exception e) {
72                 LOG.warn("Error while stopping IETF ACL ChangeListener: {}", e.getMessage());
73                 LOG.debug("Error while stopping IETF ACL ChangeListener..", e);
74             }
75             listenerRegistration = null;
76         }
77     }
78
79     @Override
80     public void remove(final InstanceIdentifier<Acl> identifier,
81                        final Acl removeDataObj) {
82         Preconditions.checkNotNull(removeDataObj, "Removed object can not be null!");
83         String aclName = removeDataObj.getAclName();
84
85         Classifiers classifiers = dbutils.read(LogicalDatastoreType.CONFIGURATION, getClassifierIid());
86         if (classifiers != null) {
87             for (Classifier classifier : classifiers.getClassifier()) {
88                 if (classifier.getAcl().equalsIgnoreCase(aclName)) {
89                     if (classifier.getSffs() != null) {
90                         for (Sff sff : classifier.getSffs().getSff()) {
91                             provider.removeClassifierRules(sff, removeDataObj);
92                         }
93                     }
94                 }
95             }
96         }
97     }
98
99     @Override
100     public void update(final InstanceIdentifier<Acl> identifier,
101                        final Acl original, final Acl update) {
102     }
103
104     @Override
105     public void add(final InstanceIdentifier<Acl> identifier,
106                     final Acl addDataObj) {
107         Preconditions.checkNotNull(addDataObj, "Added object can not be null!");
108         String aclName = addDataObj.getAclName();
109         LOG.debug("Adding accesslist iid = {}, dataObj = {}", identifier, addDataObj);
110         Classifiers classifiers = dbutils.read(LogicalDatastoreType.CONFIGURATION, getClassifierIid());
111         if (classifiers == null) {
112             LOG.debug("add: No Classifiers found");
113             return;
114         }
115
116         LOG.debug("add: Classifiers: {}", classifiers);
117         for (Classifier classifier : classifiers.getClassifier()) {
118             if (classifier.getAcl().equals(aclName)) {
119                 if (classifier.getBridges() != null) {
120                     for (Bridge bridge : classifier.getBridges().getBridge()) {
121                         provider.addClassifierRules(bridge, addDataObj);
122                     }
123                 }
124             }
125         }
126     }
127
128     private InstanceIdentifier<Classifiers> getClassifierIid() {
129         return InstanceIdentifier.create(Classifiers.class);
130     }
131
132     public InstanceIdentifier<Acl> getIetfAclIid() {
133         return InstanceIdentifier.create(AccessLists.class).child(Acl.class);
134     }
135
136     /**
137      * Create an {@link Ace} {@link InstanceIdentifier}.
138      * @param aclName is the name of the ACL
139      * @param ruleName is the name of the rule
140      * @return the {@link Ace} {@link InstanceIdentifier}
141      */
142     public InstanceIdentifier<Ace> getIetfAclEntryIid(String aclName, String ruleName) {
143         return InstanceIdentifier.create(AccessLists.class).child(Acl.class,
144                 new AclKey(aclName)).child(AccessListEntries.class).child(Ace.class,
145                 new AceKey(ruleName));
146     }
147 }