dc9ff477fc3bfa18842eb40315b12d4d7aa2e85e
[netvirt.git] / openstack / sfc-translator / impl / src / main / java / org / opendaylight / netvirt / openstack / sfc / translator / portchain / NeutronPortPairListener.java
1 /*
2  * Copyright (c) 2016 Brocade Communications 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 package org.opendaylight.netvirt.openstack.sfc.translator.portchain;
9
10 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
11 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
12 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
13 import org.opendaylight.netvirt.openstack.sfc.translator.DelegatingDataTreeListener;
14 import org.opendaylight.netvirt.openstack.sfc.translator.NeutronMdsalHelper;
15 import org.opendaylight.netvirt.openstack.sfc.translator.OvsdbMdsalHelper;
16 import org.opendaylight.netvirt.openstack.sfc.translator.SfcMdsalHelper;
17 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SffName;
18 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunction;
19 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunctionKey;
20 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder;
21 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarderBuilder;
22 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarderKey;
23 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.ServiceFunctionDictionary;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.sfc.rev160511.sfc.attributes.PortPairs;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.sfc.rev160511.sfc.attributes.port.pairs.PortPair;
27 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 import java.util.List;
32
33 /**
34  * OpenDaylight Neutron Port Pair yang models data change listener
35  */
36 public class NeutronPortPairListener extends DelegatingDataTreeListener<PortPair> {
37     private static final Logger LOG = LoggerFactory.getLogger(NeutronPortPairListener.class);
38
39     private static final InstanceIdentifier<PortPair> portPairIid =
40             InstanceIdentifier.create(Neutron.class).child(PortPairs.class).child(PortPair.class);
41
42     private final DataBroker db;
43     private final SfcMdsalHelper sfcMdsalHelper;
44     private final NeutronMdsalHelper neutronMdsalHelper;
45     private final OvsdbMdsalHelper ovsdbMdsalHelper;
46
47     public NeutronPortPairListener(DataBroker db) {
48         super(db,new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, portPairIid));
49         this.db = db;
50         sfcMdsalHelper = new SfcMdsalHelper(db);
51         neutronMdsalHelper = new NeutronMdsalHelper(db);
52         ovsdbMdsalHelper = new OvsdbMdsalHelper(db);
53     }
54
55     /**
56      * Method removes PortPair which is identified by InstanceIdentifier.
57      *
58      * @param path - the whole path to PortPair
59      * @param deletedPortPair        - PortPair for removing
60      */
61     @Override
62     public void remove(InstanceIdentifier<PortPair> path, PortPair deletedPortPair) {
63         ServiceFunctionKey sfKey = PortPairTranslator.getSFKey(deletedPortPair);
64         ServiceFunction serviceFunction = sfcMdsalHelper.readServiceFunction(sfKey);
65         if (serviceFunction != null ) {
66             //Current support is for one Service Function connected to one data plane locator
67             SffName sffName = serviceFunction.getSfDataPlaneLocator().get(0).getServiceFunctionForwarder();
68             if (sffName != null) {
69                 ServiceFunctionForwarderKey sffKey = new ServiceFunctionForwarderKey(sffName);
70                 ServiceFunctionForwarder sff = sfcMdsalHelper.readServiceFunctionForwarder(sffKey);
71                 if (sff != null) {
72                     List<ServiceFunctionDictionary> sfDictionary =  sff.getServiceFunctionDictionary();
73                     if (sfDictionary != null) {
74                         ServiceFunctionDictionary matchingSfd = null;
75                         for (ServiceFunctionDictionary sfd : sfDictionary) {
76                             if (sfd.getName().equals(sfKey.getName())) {
77                                 matchingSfd = sfd;
78                                 break;
79                             }
80                         }
81                         if (matchingSfd != null) {
82                             sfDictionary.remove(matchingSfd);
83                             if (sfDictionary.isEmpty()) {
84                                 //If the current SF is last SF attach to SFF, delete the SFF
85                                 sfcMdsalHelper.deleteServiceFunctionForwarder(sffKey);
86                             } else {
87                                 //If there are SF attached to the SFF, just update the SFF dictionary by removing
88                                 // this deleted SF.
89                                 ServiceFunctionForwarderBuilder sffBuilder = new ServiceFunctionForwarderBuilder(sff);
90                                 LOG.info("Remove the SF {} from SFF {} dictionary and update in data store.", sfKey
91                                         .getName(), sffName);
92                                 sfcMdsalHelper.addServiceFunctionForwarder(sffBuilder.build());
93                             }
94                         } else {
95                             LOG.info("Service Function {} not present in connected Service Function Forwarder {} " +
96                                     "dictionary", sfKey.getName(), sffName);
97                         }
98                     }
99                 }
100             }
101         } else {
102             LOG.info("Service Function related to Port Pair {} don't exist.", deletedPortPair);
103         }
104         sfcMdsalHelper.removeServiceFunction(sfKey);
105     }
106
107     /**
108      * Method updates the original PortPair to the update PortPair.
109      * Both are identified by same InstanceIdentifier.
110      *
111      * @param path - the whole path to PortPair
112      * @param originalPortPair   - original PortPair (for update)
113      * @param updatePortPair     - changed PortPair (contain updates)
114      */
115     @Override
116     public void update(InstanceIdentifier<PortPair> path, PortPair originalPortPair, PortPair updatePortPair) {
117         //NO-OP
118     }
119
120     /**
121      * Method adds the PortPair which is identified by InstanceIdentifier
122      * to device.
123      *
124      * @param path - the whole path to new PortPair
125      * @param newPortPair        - new PortPair
126      */
127     @Override
128     public void add(InstanceIdentifier<PortPair> path, PortPair newPortPair) {
129         //NO-OP
130         // Port Pair data written in neutron data store will be used
131         // When user will create port chain.
132     }
133 }