455eb90ac5c0c87afc9d9014ebda62d7efd8563d
[genius.git] / interfacemanager / interfacemanager-impl / src / main / java / org / opendaylight / genius / interfacemanager / servicebindings / flowbased / config / helpers / FlowBasedEgressServicesConfigUnbindHelper.java
1 /*
2  * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. 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.genius.interfacemanager.servicebindings.flowbased.config.helpers;
9
10 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
11
12 import com.google.common.util.concurrent.ListenableFuture;
13 import java.util.List;
14 import javax.inject.Inject;
15 import javax.inject.Singleton;
16 import org.apache.aries.blueprint.annotation.service.Reference;
17 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
18 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
19 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
20 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
21 import org.opendaylight.genius.mdsalutil.NwConstants;
22 import org.opendaylight.mdsal.binding.api.DataBroker;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.bound.services.state.list.BoundServicesState;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
26 import org.opendaylight.yangtools.yang.common.Uint64;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 @Singleton
31 public class FlowBasedEgressServicesConfigUnbindHelper extends AbstractFlowBasedServicesConfigUnbindHelper {
32
33     private static final Logger LOG = LoggerFactory.getLogger(FlowBasedEgressServicesConfigUnbindHelper.class);
34
35     private final ManagedNewTransactionRunner txRunner;
36     private final InterfaceManagerCommonUtils interfaceManagerCommonUtils;
37
38     @Inject
39     public FlowBasedEgressServicesConfigUnbindHelper(@Reference final DataBroker dataBroker,
40             final InterfaceManagerCommonUtils interfaceManagerCommonUtils) {
41         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
42         this.interfaceManagerCommonUtils = interfaceManagerCommonUtils;
43     }
44
45     @Override
46     protected void unbindServiceOnInterface(List<ListenableFuture<Void>> futures, BoundServices boundServiceOld,
47                                            List<BoundServices> boundServices, BoundServicesState boundServicesState) {
48         LOG.info("unbinding egress service {} for interface: {}", boundServiceOld.getServiceName(), boundServicesState
49             .getInterfaceName());
50         futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
51             Interface iface =
52                     interfaceManagerCommonUtils.getInterfaceFromConfigDS(boundServicesState.getInterfaceName());
53             Uint64 dpId = boundServicesState.getDpid();
54             if (boundServices.isEmpty()) {
55                 // Remove default entry from Lport Dispatcher Table.
56                 FlowBasedServicesUtils.removeEgressDispatcherFlows(dpId, boundServicesState.getInterfaceName(),
57                         tx, NwConstants.DEFAULT_SERVICE_INDEX);
58                 return;
59             }
60             BoundServices[] highLow =
61                     FlowBasedServicesUtils.getHighAndLowPriorityService(boundServices, boundServiceOld);
62             BoundServices low = highLow[0];
63             BoundServices high = highLow[1];
64             // This means the one removed was the highest priority service
65             if (high == null) {
66                 LOG.trace("Deleting egress dispatcher table entry for service {}, match service index {}",
67                         boundServiceOld, NwConstants.DEFAULT_SERVICE_INDEX);
68                 FlowBasedServicesUtils.removeEgressDispatcherFlows(dpId, boundServicesState.getInterfaceName(),
69                         tx, NwConstants.DEFAULT_SERVICE_INDEX);
70                 if (low != null) {
71                     //delete the lower services flow entry.
72                     LOG.trace("Deleting egress dispatcher table entry for lower service {}, match service index {}",
73                             low, low.getServicePriority());
74                     FlowBasedServicesUtils.removeEgressDispatcherFlows(dpId, boundServicesState.getInterfaceName(),
75                             tx, low.getServicePriority().toJava());
76                     BoundServices lower = FlowBasedServicesUtils.getHighAndLowPriorityService(boundServices, low)[0];
77                     short lowerServiceIndex = (short) (lower != null ? lower.getServicePriority().toJava()
78                             : low.getServicePriority().toJava() + 1);
79                     LOG.trace("Installing new egress dispatcher table entry for lower service {}, match service index "
80                                     + "{}, update service index {}",
81                             low, NwConstants.DEFAULT_SERVICE_INDEX, lowerServiceIndex);
82                     FlowBasedServicesUtils.installEgressDispatcherFlows(dpId, low,
83                             boundServicesState.getInterfaceName(), tx, boundServicesState.getIfIndex(),
84                             NwConstants.DEFAULT_SERVICE_INDEX, lowerServiceIndex, iface);
85                 }
86             } else {
87                 LOG.trace("Deleting egress dispatcher table entry for service {}, match service index {}",
88                         boundServiceOld, boundServiceOld.getServicePriority().toJava());
89                 FlowBasedServicesUtils.removeEgressDispatcherFlows(dpId, boundServicesState.getInterfaceName(),
90                         tx, boundServiceOld.getServicePriority().toJava());
91                 short lowerServiceIndex = (short) (low != null ? low.getServicePriority().toJava()
92                         : boundServiceOld.getServicePriority().toJava() + 1);
93                 BoundServices highest = FlowBasedServicesUtils.getHighestPriorityService(boundServices);
94                 if (high.equals(highest)) {
95                     LOG.trace("Update the existing higher service {}, match service index {}, update service index {}",
96                             high, NwConstants.DEFAULT_SERVICE_INDEX, lowerServiceIndex);
97                     FlowBasedServicesUtils.installEgressDispatcherFlows(dpId, high,
98                             boundServicesState.getInterfaceName(), tx, boundServicesState.getIfIndex(),
99                             NwConstants.DEFAULT_SERVICE_INDEX, lowerServiceIndex, iface);
100                 } else {
101                     LOG.trace("Update the existing higher service {}, match service index {}, update service index {}",
102                             high, high.getServicePriority().toJava(), lowerServiceIndex);
103                     FlowBasedServicesUtils.installEgressDispatcherFlows(dpId, high,
104                             boundServicesState.getInterfaceName(), tx, boundServicesState.getIfIndex(),
105                             high.getServicePriority().toJava(), lowerServiceIndex, iface);
106                 }
107             }
108         }));
109     }
110
111     @Override
112     protected void unbindServiceOnInterfaceType(List<ListenableFuture<Void>> futures, BoundServices boundServiceNew,
113                                                 List<BoundServices> allServices) {
114         LOG.info("Tunnel Type based egress service unbinding - WIP");
115     }
116 }