Convert to JobCoordinator in policyservice-impl
[netvirt.git] / vpnservice / policyservice / impl / src / main / java / org / opendaylight / netvirt / policyservice / PolicyRouteFlowProgrammer.java
1 /*
2  * Copyright (c) 2017 Hewlett Packard Enterprise, Co. 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.netvirt.policyservice;
10
11 import com.google.common.base.Optional;
12 import java.math.BigInteger;
13 import java.util.Collections;
14 import java.util.List;
15 import javax.inject.Inject;
16 import javax.inject.Singleton;
17 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
18 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
19 import org.opendaylight.genius.mdsalutil.InstructionInfo;
20 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
21 import org.opendaylight.genius.mdsalutil.NwConstants;
22 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
23 import org.opendaylight.netvirt.policyservice.util.PolicyServiceFlowUtil;
24 import org.opendaylight.netvirt.policyservice.util.PolicyServiceUtil;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 /**
30  * Program POLICY_ROUTING_TABLE flows. Each flow is composed from<br>
31  * * OF matches - logical tunnel lport tag and policy classifier metadata
32  * bits<br>
33  * * OF actions - set policy classifier group id based on the remote DPN
34  * associated with the logical tunnel.
35  *
36  */
37 @SuppressWarnings("deprecation")
38 @Singleton
39 public class PolicyRouteFlowProgrammer {
40     private static final Logger LOG = LoggerFactory.getLogger(PolicyRouteFlowProgrammer.class);
41
42     private final DataBroker dataBroker;
43     private final PolicyIdManager policyIdManager;
44     private final PolicyServiceUtil policyServiceUtil;
45     private final PolicyServiceFlowUtil policyFlowUtil;
46     private final JobCoordinator coordinator;
47
48     @Inject
49     public PolicyRouteFlowProgrammer(final DataBroker dataBroker, final PolicyIdManager policyIdManager,
50             final PolicyServiceUtil policyServiceUtil, final PolicyServiceFlowUtil policyFlowUtil,
51             final JobCoordinator coordinator) {
52         this.dataBroker = dataBroker;
53         this.policyIdManager = policyIdManager;
54         this.policyServiceUtil = policyServiceUtil;
55         this.policyFlowUtil = policyFlowUtil;
56         this.coordinator = coordinator;
57     }
58
59     public void programPolicyClassifierFlows(String policyClassifierName, List<BigInteger> localDpIds,
60             List<BigInteger> remoteDpIds, int addOrRemove) {
61         long policyClassifierId = policyIdManager.getPolicyClassifierId(policyClassifierName);
62         if (policyClassifierId == PolicyServiceConstants.INVALID_ID) {
63             LOG.error("Failed to get policy classifier id for classifier {}", policyClassifierName);
64             return;
65         }
66
67         coordinator.enqueueJob(policyClassifierName, () -> {
68             WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
69             remoteDpIds.forEach(remoteDpId -> {
70                 long groupId = policyIdManager.getPolicyClassifierGroupId(policyClassifierName, remoteDpId);
71                 if (groupId != PolicyServiceConstants.INVALID_ID) {
72                     List<InstructionInfo> instructions = policyFlowUtil.getPolicyRouteInstructions(groupId);
73                     localDpIds.forEach(localDpId -> {
74                         if (!remoteDpId.equals(localDpId)) {
75                             programPolicyClassifierFlow(policyClassifierName, policyClassifierId, instructions,
76                                     localDpId, remoteDpId, tx, addOrRemove);
77                         }
78                     });
79                 } else {
80                     LOG.error("Failed to get group id for policy classifier {} DPN {}", policyClassifierName,
81                             remoteDpId);
82                 }
83             });
84             return Collections.singletonList(tx.submit());
85         });
86
87     }
88
89     public void programPolicyClassifierFlow(String policyClassifierName, BigInteger localDpId, BigInteger remoteDpId,
90             int addOrRemove) {
91         programPolicyClassifierFlow(policyClassifierName, localDpId, remoteDpId, addOrRemove, false);
92     }
93
94     public void programPolicyClassifierFlow(String policyClassifierName, BigInteger localDpId, BigInteger remoteDpId,
95             int addOrRemove, boolean createIfMissing) {
96         long policyClassifierId = policyIdManager.getPolicyClassifierId(policyClassifierName);
97         if (policyClassifierId == PolicyServiceConstants.INVALID_ID) {
98             LOG.error("Failed to get policy classifier id for classifier {}", policyClassifierName);
99             return;
100         }
101
102         long groupId = policyIdManager.getPolicyClassifierGroupId(policyClassifierName, remoteDpId);
103         if (groupId == PolicyServiceConstants.INVALID_ID) {
104             LOG.error("Failed to get group id for policy classifier {} DPN {}", policyClassifierName, remoteDpId);
105             return;
106         }
107
108         if (addOrRemove == NwConstants.ADD_FLOW && createIfMissing) {
109             addPolicyClassifierGroup(policyClassifierName, localDpId, remoteDpId, addOrRemove, groupId);
110         }
111
112         List<InstructionInfo> instructions = policyFlowUtil.getPolicyRouteInstructions(groupId);
113         coordinator.enqueueJob(policyClassifierName, () -> {
114             WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
115             programPolicyClassifierFlow(policyClassifierName, policyClassifierId, instructions, localDpId, remoteDpId,
116                     tx, addOrRemove);
117             return Collections.singletonList(tx.submit());
118         });
119
120     }
121
122     private void programPolicyClassifierFlow(String policyClassifierName, long policyClassifierId,
123             List<InstructionInfo> instructions, BigInteger localDpId, BigInteger remoteDpId, WriteTransaction tx,
124             int addOrRemove) {
125         Optional<Integer> lportTagOpt = policyServiceUtil.getLogicalTunnelLportTag(localDpId, remoteDpId);
126         if (!lportTagOpt.isPresent()) {
127             LOG.debug("Missing lport-tag for policy classifier {} logical tunnel for source DPN {} dst DPN {}",
128                     policyClassifierName, localDpId, remoteDpId);
129             return;
130         }
131
132         List<MatchInfoBase> matches = policyFlowUtil.getPolicyRouteMatches(policyClassifierId, lportTagOpt.get());
133         LOG.debug("{} policy classifier {} route on source DPN {} dest DPN {}",
134                 addOrRemove == NwConstants.ADD_FLOW ? "Installing" : "Removing", policyClassifierName, localDpId,
135                 remoteDpId);
136         policyFlowUtil.updateFlowToTx(localDpId, NwConstants.EGRESS_POLICY_ROUTING_TABLE,
137                 PolicyIdManager.getPolicyClassifierGroupKey(policyClassifierName, remoteDpId),
138                 PolicyServiceConstants.POLICY_FLOW_PRIOPITY, NwConstants.EGRESS_POLICY_ROUTING_COOKIE, matches,
139                 instructions, addOrRemove, tx);
140     }
141
142     private void addPolicyClassifierGroup(String policyClassifierName, BigInteger localDpId, BigInteger remoteDpId,
143             int addOrRemove, long groupId) {
144         coordinator.enqueueJob(policyClassifierName, () -> {
145             WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
146             policyFlowUtil.updateGroupToTx(localDpId, groupId,
147                     PolicyIdManager.getPolicyClassifierGroupKey(policyClassifierName, remoteDpId), GroupTypes.GroupFf,
148                     addOrRemove, tx);
149             return Collections.singletonList(tx.submit());
150         });
151     }
152
153 }