Moving TableIds into a single constants file
[vpnservice.git] / interfacemgr / interfacemgr-impl / src / main / java / org / opendaylight / vpnservice / interfacemgr / servicebindings / flowbased / confighelpers / FlowBasedServicesConfigBindHelper.java
1 /*
2  * Copyright (c) 2015 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.vpnservice.interfacemgr.servicebindings.flowbased.confighelpers;
9
10 import com.google.common.util.concurrent.ListenableFuture;
11 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
12 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
13 import org.opendaylight.vpnservice.interfacemgr.IfmConstants;
14 import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
15 import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
16 import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
17 import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
18 import org.opendaylight.vpnservice.mdsalutil.NwConstants;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfo;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
28 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 import java.math.BigInteger;
33 import java.util.ArrayList;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.concurrent.ConcurrentHashMap;
37
38 public class FlowBasedServicesConfigBindHelper {
39     private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesConfigBindHelper.class);
40
41     public static List<ListenableFuture<Void>> bindService(InstanceIdentifier<BoundServices> instanceIdentifier,
42                                                            BoundServices boundServiceNew, DataBroker dataBroker) {
43         List<ListenableFuture<Void>> futures = new ArrayList<>();
44         WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
45         String interfaceName =
46                 InstanceIdentifier.keyOf(instanceIdentifier.firstIdentifierOf(ServicesInfo.class)).getInterfaceName();
47
48         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
49                 InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker);
50         if (ifState == null || ifState.getOperStatus() == OperStatus.Down) {
51             LOG.warn("Interface not up, not Binding Service for Interface: {}", interfaceName);
52             return futures;
53         }
54
55         // Get the Parent ServiceInfo
56
57         ServicesInfo servicesInfo = FlowBasedServicesUtils.getServicesInfoForInterface(interfaceName, dataBroker);
58         if (servicesInfo == null) {
59             LOG.error("Reached Impossible part 1 in the code during bind service for: {}", boundServiceNew);
60             return futures;
61         }
62
63         InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
64         Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
65
66         List<BoundServices> allServices = servicesInfo.getBoundServices();
67         if (allServices.isEmpty()) {
68             LOG.error("Reached Impossible part 2 in the code during bind service for: {}", boundServiceNew);
69             return futures;
70         }
71
72         NodeConnectorId nodeConnectorId = FlowBasedServicesUtils.getNodeConnectorIdFromInterface(iface, dataBroker);
73         long portNo = Long.parseLong(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId));
74         BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
75
76         if (allServices.size() == 1) {
77             // If only one service present, install instructions in table 0.
78             int vlanId = 0;
79             List<MatchInfo> matches = null;
80             if (iface.getType().isAssignableFrom(L2vlan.class)) {
81                 matches = FlowBasedServicesUtils.getMatchInfoForVlanPortAtIngressTable(dpId, portNo, iface);
82             } else if (iface.getType().isAssignableFrom(Tunnel.class)){
83                 matches = FlowBasedServicesUtils.getMatchInfoForTunnelPortAtIngressTable (dpId, portNo, iface);
84             }
85
86             if (matches != null) {
87                 FlowBasedServicesUtils.installInterfaceIngressFlow(dpId, iface, boundServiceNew,
88                         transaction, matches, ifState.getIfIndex(), NwConstants.VLAN_INTERFACE_INGRESS_TABLE);
89             }
90
91             if (transaction != null) {
92                 futures.add(transaction.submit());
93             }
94             return futures;
95         }
96
97         boolean isCurrentServiceHighestPriority = true;
98         Map<Short, BoundServices> tmpServicesMap = new ConcurrentHashMap<>();
99         short highestPriority = 0xFF;
100         for (BoundServices boundService : allServices) {
101             if (boundService.getServicePriority() < boundServiceNew.getServicePriority()) {
102                 isCurrentServiceHighestPriority = false;
103                 break;
104             }
105             if (!boundService.equals(boundServiceNew)) {
106                 tmpServicesMap.put(boundService.getServicePriority(), boundService);
107                 if (boundService.getServicePriority() < highestPriority) {
108                     highestPriority = boundService.getServicePriority();
109                 }
110             }
111         }
112
113         if (!isCurrentServiceHighestPriority) {
114             FlowBasedServicesUtils.installLPortDispatcherFlow(dpId, boundServiceNew, iface, transaction,
115                     ifState.getIfIndex());
116         } else {
117             BoundServices serviceToReplace = tmpServicesMap.get(highestPriority);
118             FlowBasedServicesUtils.installLPortDispatcherFlow(dpId, serviceToReplace, iface, transaction,
119                     ifState.getIfIndex());
120             List<MatchInfo> matches = null;
121             if (iface.getType().isAssignableFrom(L2vlan.class)) {
122                 matches = FlowBasedServicesUtils.getMatchInfoForVlanPortAtIngressTable(dpId, portNo, iface);
123             } else if (iface.getType().isAssignableFrom(Tunnel.class)){
124                 matches = FlowBasedServicesUtils.getMatchInfoForTunnelPortAtIngressTable (dpId, portNo, iface);
125             }
126
127             if (matches != null) {
128
129                 WriteTransaction removeFlowTransaction = dataBroker.newWriteOnlyTransaction();
130                 FlowBasedServicesUtils.removeIngressFlow(iface, serviceToReplace, dpId, removeFlowTransaction);
131                 futures.add(removeFlowTransaction.submit());
132
133                 WriteTransaction installFlowTransaction = dataBroker.newWriteOnlyTransaction();
134                 FlowBasedServicesUtils.installInterfaceIngressFlow(dpId, iface, boundServiceNew, installFlowTransaction,
135                         matches, ifState.getIfIndex(), NwConstants.VLAN_INTERFACE_INGRESS_TABLE);
136                 futures.add(installFlowTransaction.submit());
137             }
138         }
139
140         if (transaction != null) {
141             futures.add(transaction.submit());
142         }
143         return futures;
144     }
145 }