Bump versions by 0.1.0 for next dev cycle
[vpnservice.git] / interfacemgr / interfacemgr-impl / src / main / java / org / opendaylight / vpnservice / interfacemgr / servicebindings / flowbased / statehelpers / FlowBasedServicesStateBindHelper.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.statehelpers;
9
10 import com.google.common.util.concurrent.ListenableFuture;
11
12 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
13 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
14 import org.opendaylight.vpnservice.interfacemgr.IfmConstants;
15 import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
16 import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
17 import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
18 import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
19 import org.opendaylight.vpnservice.mdsalutil.NwConstants;
20 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfo;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
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.Collection;
35 import java.util.Collections;
36 import java.util.Comparator;
37 import java.util.List;
38
39 public class FlowBasedServicesStateBindHelper {
40     private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesStateBindHelper.class);
41
42     public static List<ListenableFuture<Void>> bindServicesOnInterface(Interface ifaceState,
43                                                              DataBroker dataBroker) {
44         List<ListenableFuture<Void>> futures = new ArrayList<>();
45         ServicesInfo servicesInfo = FlowBasedServicesUtils.getServicesInfoForInterface(ifaceState.getName(), dataBroker);
46         if (servicesInfo == null) {
47             return futures;
48         }
49
50         List<BoundServices> allServices = servicesInfo.getBoundServices();
51         if (allServices == null || allServices.isEmpty()) {
52             return futures;
53         }
54
55         InterfaceKey interfaceKey = new InterfaceKey(ifaceState.getName());
56         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
57                     InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
58
59         if (iface.getType().isAssignableFrom(L2vlan.class)) {
60             return bindServiceOnVlan(allServices, iface, ifaceState.getIfIndex(), dataBroker);
61         } else if (iface.getType().isAssignableFrom(Tunnel.class)){
62              return bindServiceOnTunnel(allServices, iface, ifaceState.getIfIndex(), dataBroker);
63         }
64         return futures;
65     }
66
67     private static List<ListenableFuture<Void>> bindServiceOnTunnel(
68             List<BoundServices> allServices,
69             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface,
70             Integer ifIndex, DataBroker dataBroker) {
71         List<ListenableFuture<Void>> futures = new ArrayList<>();
72         NodeConnectorId nodeConnectorId = FlowBasedServicesUtils.getNodeConnectorIdFromInterface(iface, dataBroker);
73         long portNo = Long.parseLong(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId));
74         BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
75         List<MatchInfo> matches = FlowBasedServicesUtils.getMatchInfoForTunnelPortAtIngressTable (dpId, portNo, iface);
76         BoundServices highestPriorityBoundService = FlowBasedServicesUtils.getHighestPriorityService(allServices);
77         WriteTransaction t = dataBroker.newWriteOnlyTransaction();
78         if (matches != null) {
79             FlowBasedServicesUtils.installInterfaceIngressFlow(dpId, iface, highestPriorityBoundService,
80                     t, matches, ifIndex, NwConstants.VLAN_INTERFACE_INGRESS_TABLE);
81         }
82
83         for (BoundServices boundService : allServices) {
84             if (!boundService.equals(highestPriorityBoundService)) {
85                 FlowBasedServicesUtils.installLPortDispatcherFlow(dpId, boundService, iface, t, ifIndex, boundService.getServicePriority(), (short) (boundService.getServicePriority()+1));
86             }
87         }
88
89         futures.add(t.submit());
90         return futures;
91     }
92
93     private static List<ListenableFuture<Void>> bindServiceOnVlan(
94             List<BoundServices> allServices,
95             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface,
96             Integer ifIndex, DataBroker dataBroker) {
97         List<ListenableFuture<Void>> futures = new ArrayList<>();
98         NodeConnectorId nodeConnectorId = FlowBasedServicesUtils.getNodeConnectorIdFromInterface(iface, dataBroker);
99         BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
100         WriteTransaction t = dataBroker.newWriteOnlyTransaction();
101         Collections.sort(allServices, new Comparator<BoundServices>() {
102             @Override
103             public int compare(BoundServices serviceInfo1, BoundServices serviceInfo2) {
104                 return serviceInfo1.getServicePriority().compareTo(serviceInfo2.getServicePriority());
105             }
106         });
107         BoundServices highestPriority = allServices.remove(0);
108         short nextServiceIndex = (short) (allServices.size() > 0 ? allServices.get(0).getServicePriority() : highestPriority.getServicePriority() + 1);
109         FlowBasedServicesUtils.installLPortDispatcherFlow(dpId, highestPriority, iface, t, ifIndex, IfmConstants.DEFAULT_SERVICE_INDEX, nextServiceIndex);
110         BoundServices prev = null;
111         for (BoundServices boundService : allServices) {
112             if (prev!=null) {
113                 FlowBasedServicesUtils.installLPortDispatcherFlow(dpId, prev, iface, t, ifIndex, prev.getServicePriority(), boundService.getServicePriority());
114             }
115             prev = boundService;
116         }
117         if (prev!=null) {
118             FlowBasedServicesUtils.installLPortDispatcherFlow(dpId, prev, iface, t, ifIndex, prev.getServicePriority(), (short) (prev.getServicePriority()+1));
119         }
120         futures.add(t.submit());
121         return futures;
122
123     }
124
125 }