apply checkstyle check during build for neutron-mapper
[groupbasedpolicy.git] / neutron-mapper / src / main / java / org / opendaylight / groupbasedpolicy / neutron / mapper / mapping / rule / SingleClassifierRule.java
1 /*
2  * Copyright (c) 2014 Cisco 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
9 package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule;
10
11 import com.google.common.annotations.VisibleForTesting;
12 import com.google.common.collect.ImmutableList;
13
14 import java.util.List;
15
16 import javax.annotation.concurrent.Immutable;
17
18 import org.opendaylight.groupbasedpolicy.api.sf.EtherTypeClassifierDefinition;
19 import org.opendaylight.groupbasedpolicy.api.sf.IpProtoClassifierDefinition;
20 import org.opendaylight.groupbasedpolicy.api.sf.L4ClassifierDefinition;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.change.action.of.security.group.rules.input.action.ActionChoice;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.change.action.of.security.group.rules.input.action.action.choice.SfcActionCase;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.Rule;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.RuleBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.rules.attributes.security.rules.SecurityRule;
29
30 @Immutable
31 public class SingleClassifierRule {
32
33     private final ClassifierInstance classifierInstance;
34     private final ClassifierRef classifierRef;
35     private final Rule rule;
36
37     public SingleClassifierRule(SecurityRule secRule, int ruleBaseOrder, ActionChoice action) {
38         classifierInstance = SecRuleEntityDecoder.getClassifierInstance(secRule);
39         classifierRef = SecRuleEntityDecoder.getClassifierRef(secRule);
40         rule = createRule(
41                 updateOrderBasedOn(classifierInstance, action, ruleBaseOrder),
42                 secRule,
43                 action);
44     }
45
46     public ClassifierInstance getClassifierInstance() {
47         return classifierInstance;
48     }
49
50     public ClassifierRef getClassifierRef() {
51         return classifierRef;
52     }
53
54     public Rule getRule() {
55         return rule;
56     }
57
58     private Rule createRule(int order, SecurityRule secRule, ActionChoice action) {
59         return new RuleBuilder().setName(SecRuleNameDecoder.getRuleName(secRule))
60             .setOrder(order)
61             .setActionRef(ImmutableList.of(SecRuleEntityDecoder.createActionRefFromActionChoice(action)))
62             .setClassifierRef(ImmutableList.<ClassifierRef>of(classifierRef))
63             .build();
64     }
65
66     /**
67      * Increases initial order of potential {@link Rule} containing single
68      * {@link ClassifierInstance} based on parameter values of the instance.
69      * <br>
70      * The following section describes how L4 port specification is prioritized
71      * from most specific to least specific:<br>
72      * 1) src port AND dst port<br>
73      * 2) (src port range AND dst port) OR (src port AND dst port range)<br>
74      * 3) src port range AND dst port range<br>
75      * 4) src port OR dst port<br>
76      * 5) src port range OR dst port range<br>
77      *
78      * @param ci instance object of {@link ClassifierInstance}
79      * @param baseOrder initial order value calculated for the {@link Rule}
80      * @return value of incremented order based on parameter values.
81      *
82      * @see ParameterValue
83      */
84     @VisibleForTesting
85     static int updateOrderBasedOn(ClassifierInstance ci, ActionChoice action, Integer baseOrder) {
86         int delta = 0;
87         if (ci.getClassifierDefinitionId().equals(EtherTypeClassifierDefinition.ID)) {
88             delta = 350;
89         } else if (ci.getClassifierDefinitionId().equals(IpProtoClassifierDefinition.ID)) {
90             delta = 300;
91         } else if (ci.getClassifierDefinitionId().equals(L4ClassifierDefinition.ID)) {
92             delta = 200;
93             List<ParameterValue> parameterValue = ci.getParameterValue();
94             for (ParameterValue pv : parameterValue) {
95                 // SRC/DST_PORT_PARAM is considered to be more
96                 // specific than SRC/DST_PORT_RANGE_PARAM.
97                 if (isSrcOrDstPortParam(pv)) {
98                     delta -= 30;
99                 } else if (isRangePortParam(pv)) {
100                     delta -= pv.getRangeValue().getMin().equals(pv.getRangeValue().getMax()) ? 30 : 20;
101                 }
102             }
103         }
104         if (action instanceof SfcActionCase) {
105             delta -= 5;
106         }
107         // more specific CIs should have lower order calculated.
108         return baseOrder + delta;
109     }
110
111     private static boolean isRangePortParam(ParameterValue pv) {
112         String pvName = pv.getName().getValue();
113         return pv.getRangeValue() != null && (pvName.equals(L4ClassifierDefinition.SRC_PORT_RANGE_PARAM)
114             || pvName.equals(L4ClassifierDefinition.DST_PORT_RANGE_PARAM));
115     }
116
117     private static boolean isSrcOrDstPortParam(ParameterValue pv) {
118         String pvName = pv.getName().getValue();
119         return pv.getIntValue() != null && (pvName.equals(L4ClassifierDefinition.SRC_PORT_PARAM)
120             || pvName.equals(L4ClassifierDefinition.DST_PORT_PARAM));
121     }
122
123 }