Merge "Unit test for ovsdb.southbound.ovsdb.transact"
[netvirt.git] / openstack / net-virt-sfc / impl / src / main / java / org / opendaylight / ovsdb / openstack / netvirt / sfc / NetvirtSfcClassifierListener.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.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.Classifiers;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.Classifier;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.sffs.Sff;
23 import org.opendaylight.yangtools.concepts.ListenerRegistration;
24 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 /**
29  * Data tree listener for Classifier.
30  *
31  * @author Arun Yerra
32  */
33 public class NetvirtSfcClassifierListener extends AbstractDataTreeListener<Classifier> {
34     private static final Logger LOG = LoggerFactory.getLogger(NetvirtSfcClassifierListener.class);
35     private MdsalUtils dbutils;
36     private ListenerRegistration<NetvirtSfcClassifierListener> listenerRegistration;
37
38     /**
39      * {@link NetvirtSfcClassifierListener} constructor.
40      * @param provider OpenFlow 1.3 Provider
41      * @param db MdSal {@link DataBroker}
42      */
43     public NetvirtSfcClassifierListener(final INetvirtSfcOF13Provider provider, final DataBroker db) {
44         super(provider, Classifier.class);
45         Preconditions.checkNotNull(db, "DataBroker can not be null!");
46         dbutils = new MdsalUtils(db);
47         registrationListener(db);
48     }
49
50     private void registrationListener(final DataBroker db) {
51         final DataTreeIdentifier<Classifier> treeId =
52                 new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, getClassifierIid());
53         try {
54             LOG.info("Registering Data Change Listener for NetvirtSfc Classifier configuration.");
55             listenerRegistration = db.registerDataTreeChangeListener(treeId, this);
56         } catch (final Exception e) {
57             LOG.warn("Netvirt Classifier DataChange listener registration fail!");
58             LOG.debug("Netvirt Classifier DataChange listener registration fail!", e);
59             throw new IllegalStateException("NetvirtSfcClassifierListener startup fail! System needs restart.", e);
60         }
61     }
62
63     @Override
64     public void close() {
65         if (listenerRegistration != null) {
66             try {
67                 listenerRegistration.close();
68             } catch (final Exception e) {
69                 LOG.warn("Error to stop Netvirt Classifier DataChange listener: {}", e.getMessage());
70                 LOG.debug("Error to stop Netvirt Classifier DataChange listener..", e);
71             }
72             listenerRegistration = null;
73         }
74     }
75
76     @Override
77     public void remove(final InstanceIdentifier<Classifier> identifier,
78                        final Classifier removeDataObj) {
79         Preconditions.checkNotNull(removeDataObj, "Added object can not be null!");
80         String aclName = removeDataObj.getAcl();
81         // Read the ACL information from data store and make sure it exists.
82         Acl acl = dbutils.read(LogicalDatastoreType.CONFIGURATION, getIetfAclIid(aclName));
83         if (acl == null) {
84             LOG.debug("IETF ACL with name ={} is not yet configured. skip this operation", aclName);
85             return;
86         }
87
88         if (removeDataObj.getSffs() != null) {
89             for (Sff sff : removeDataObj.getSffs().getSff()) {
90                 // Netvirt classifier binds an ACL with service function forwarder that is identified by SFF name.
91                 // SFF validation can be done with SFC Provider APIs, as SFF is configured within SFC project.  
92                 // Netvirt SFC provider will validate the SFF using SFC provider APIs.
93                 provider.removeClassifierRules(sff, acl);
94             }
95         }
96     }
97
98     @Override
99     public void update(final InstanceIdentifier<Classifier> identifier,
100                        final Classifier original, final Classifier update) {
101         //TODO
102
103     }
104
105     @Override
106     public void add(final InstanceIdentifier<Classifier> identifier,
107                     final Classifier addDataObj) {
108         Preconditions.checkNotNull(addDataObj, "Added object can not be null!");
109         String aclName = addDataObj.getAcl();
110         // Read the ACL information from data store and make sure it exists.
111         Acl acl = dbutils.read(LogicalDatastoreType.CONFIGURATION,getIetfAclIid(aclName));
112         if (acl == null) {
113             LOG.debug("IETF ACL with name ={} is not yet configured. skip this operation", aclName);
114             return;
115         }
116
117         if (addDataObj.getSffs() != null) {
118             for (Sff sff : addDataObj.getSffs().getSff()) {
119                 // Netvirt classifier binds an ACL with service function forwarder that is identified by SFF name.
120                 // SFF validation can be done with SFC Provider APIs, as SFF is configured within SFC project.  
121                 // Netvirt SFC provider will validate the SFF using SFC provider APIs.
122                 provider.addClassifierRules(sff, acl);
123             }
124         }
125     }
126
127     public InstanceIdentifier<Classifier> getClassifierIid() {
128         return InstanceIdentifier.create(Classifiers.class).child(Classifier.class);
129     }
130
131     private InstanceIdentifier<Acl> getIetfAclIid(String aclName) {
132         return InstanceIdentifier.create(AccessLists.class).child(Acl.class, new AclKey(aclName));
133     }
134 }