Fix of the logical OR behaviour within a rule and update of error messages accross all the
classifiers.
Change-Id: Id1e5157915772e13fcc5ff431321c40d3863ffdc
Signed-off-by: Tomas Cechvala <tcechval@cisco.com>
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.Classifier;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.ParamDerivator;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.SubjectFeatures;
-import org.opendaylight.groupbasedpolicy.resolver.ConditionGroup;
import org.opendaylight.groupbasedpolicy.resolver.EgKey;
import org.opendaylight.groupbasedpolicy.resolver.EndpointConstraint;
import org.opendaylight.groupbasedpolicy.resolver.IndexedTenant;
}
classifiers.add(new ClassifierDefinitionId(ci.getClassifierDefinitionId()));
for (ParameterValue v : ci.getParameterValue()) {
-
- if (v.getIntValue() != null) {
- paramsFromClassifier.put(v.getName().getValue(), v);
- } else if (v.getStringValue() != null) {
- paramsFromClassifier.put(v.getName().getValue(), v);
- } else if (v.getRangeValue() != null) {
- paramsFromClassifier.put(v.getName().getValue(), v);
+ if (paramsFromClassifier.get(v.getName().getValue()) == null) {
+ if (v.getIntValue() != null
+ || v.getStringValue() != null
+ || v.getRangeValue() != null) {
+ paramsFromClassifier.put(v.getName().getValue(), v);
+ }
+ } else {
+ if (!paramsFromClassifier.get(v.getName().getValue()).equals(v)) {
+ throw new IllegalArgumentException("Classification error in rule: " + rule.getName()
+ + ".\nCause: " + "Classification conflict detected at parameter " + v.getName());
+ }
}
}
}
+ if(classifiers.isEmpty()) {
+ return;
+ }
List<Map<String, ParameterValue>> derivedParamsByName = ParamDerivator.ETHER_TYPE_DERIVATOR.deriveParameter(paramsFromClassifier);
-
+ String baseId = createBaseFlowId(direction, cgPair, priority);
+ List<MatchBuilder> flowMatchBuilders = new ArrayList<>();
for (Map<String, ParameterValue> params : derivedParamsByName) {
- for (ClassifierDefinitionId clDefId : classifiers) {
- // XXX - TODO - implement connection tracking (requires openflow
- // extension and data plane support - in 2.4. Will need to handle
- // case where we are working with mix of nodes.
-
- List<MatchBuilder> matches = new ArrayList<>();
- if (cgPair.sIpPrefixes.isEmpty() && cgPair.dIpPrefixes.isEmpty()) {
- matches.add(createBaseMatch(direction, cgPair, null, null));
- } else if (!cgPair.sIpPrefixes.isEmpty() && cgPair.dIpPrefixes.isEmpty()) {
- for (IpPrefix sIpPrefix : cgPair.sIpPrefixes) {
- matches.add(createBaseMatch(direction, cgPair, sIpPrefix, null));
- }
- } else if (cgPair.sIpPrefixes.isEmpty() && !cgPair.dIpPrefixes.isEmpty()) {
+ List<MatchBuilder> matchBuildersToResolve = new ArrayList<>();
+ if (cgPair.sIpPrefixes.isEmpty() && cgPair.dIpPrefixes.isEmpty()) {
+ matchBuildersToResolve.add(createBaseMatch(direction, cgPair, null, null));
+ } else if (!cgPair.sIpPrefixes.isEmpty() && cgPair.dIpPrefixes.isEmpty()) {
+ for (IpPrefix sIpPrefix : cgPair.sIpPrefixes) {
+ matchBuildersToResolve.add(createBaseMatch(direction, cgPair, sIpPrefix, null));
+ }
+ } else if (cgPair.sIpPrefixes.isEmpty() && !cgPair.dIpPrefixes.isEmpty()) {
+ for (IpPrefix dIpPrefix : cgPair.sIpPrefixes) {
+ matchBuildersToResolve.add(createBaseMatch(direction, cgPair, null, dIpPrefix));
+ }
+ } else {
+ for (IpPrefix sIpPrefix : cgPair.sIpPrefixes) {
for (IpPrefix dIpPrefix : cgPair.sIpPrefixes) {
- matches.add(createBaseMatch(direction, cgPair, null, dIpPrefix));
- }
- } else {
- for (IpPrefix sIpPrefix : cgPair.sIpPrefixes) {
- for (IpPrefix dIpPrefix : cgPair.sIpPrefixes) {
- matches.add(createBaseMatch(direction, cgPair, sIpPrefix, dIpPrefix));
- }
+ matchBuildersToResolve.add(createBaseMatch(direction, cgPair, sIpPrefix, dIpPrefix));
}
}
-
+ }
+ for (ClassifierDefinitionId clDefId : classifiers) {
Classifier classifier = SubjectFeatures.getClassifier(clDefId);
- ClassificationResult result = classifier.updateMatch(matches, params);
+ ClassificationResult result = classifier.updateMatch(matchBuildersToResolve, params);
if (!result.isSuccessfull()) {
// TODO consider different handling.
- throw new IllegalArgumentException(result.getErrorMessage());
+ throw new IllegalArgumentException("Classification conflict detected in rule: " + rule.getName() + ".\nCause: "
+ + result.getErrorMessage());
}
- String baseId = createBaseFlowId(direction, cgPair, priority);
+ matchBuildersToResolve = new ArrayList<>(result.getMatchBuilders());
+ }
+ flowMatchBuilders.addAll(matchBuildersToResolve);
+ }
FlowBuilder flow = base().setPriority(Integer.valueOf(priority));
- for (MatchBuilder match : result.getMatchBuilders()) {
+ for (MatchBuilder match : flowMatchBuilders) {
Match m = match.build();
FlowId flowId = new FlowId(baseId + "|" + m.toString());
flow.setMatch(m)
.setInstructions(instructions(applyActionIns(actionBuilderList)));
flowMap.writeFlow(netElements.getNodeId(), TABLE_ID, flow.build());
}
- }
- }
}
private String createBaseFlowId(Direction direction, CgPair cgPair, int priority) {
*/
public final ClassificationResult updateMatch(List<MatchBuilder> matches, Map<String, ParameterValue> params) {
if (params == null) {
- return new ClassificationResult("Classifier: {" + this.getClassDef().getName() + "} No parameters present.");
+ return new ClassificationResult("Classifier-instance with classifier-definition-id: " + this.getId()
+ + ". No parameters present.");
}
List<MatchBuilder> matchBuilders = matches;
try {
if (!Strings.isNullOrEmpty(e.getMessage())) {
return new ClassificationResult(e.getMessage());
} else
- return new ClassificationResult("Error while processing data of " + this.getClassDef().getName()
- + " classifier. Classification was not successful.");
+ return new ClassificationResult("Classifier-instance with classifier-definition-id: " + this.getId()
+ + ". Classification was not successful.");
}
return new ClassificationResult(matchBuilders);
}
@Override
protected void checkPresenceOfRequiredParams(Map<String, ParameterValue> params) {
if (params.get(ETHERTYPE_PARAM) == null) {
- throw new IllegalArgumentException("Classifier: {" + this.getClassDef().getName()
- + "}+ Parameter ethertype not present.");
+ throw new IllegalArgumentException("Parameter " + ETHERTYPE_PARAM + " not specified.");
}
if (params.get(ETHERTYPE_PARAM).getIntValue() == null) {
- throw new IllegalArgumentException("Classifier: {" + this.getClassDef().getName()
- + "}+ Value of ethertype parameter is not present.");
+ throw new IllegalArgumentException("Value of " + ETHERTYPE_PARAM + " parameter is not present.");
}
}
private void equalOrNotSetValidation(EthernetType ethTypeInMatch, long paramValue) {
if (ethTypeInMatch != null) {
if (paramValue != ethTypeInMatch.getType().getValue().longValue()) {
- throw new IllegalArgumentException("Classification conflict at " + this.getClassDef().getName()
- + ": Trying to override ether-type value: " + ethTypeInMatch.getType().getValue()
- + " by value " + paramValue);
+ throw new IllegalArgumentException("Classification conflict detected at " + ETHERTYPE_PARAM
+ + " parameter for values " + ethTypeInMatch.getType().getValue() + " and " + paramValue
+ + ". It is not allowed "
+ + "to assign different values to the same parameter among all the classifiers within one rule.");
}
}
}
@Override
protected void checkPresenceOfRequiredParams(Map<String, ParameterValue> params) {
if (params.get(PROTO_PARAM) == null) {
- throw new IllegalArgumentException("Classifier: {" + this.getClassDef().getName()
- + "}+ Parameter proto not present.");
+ throw new IllegalArgumentException("Parameter " + PROTO_PARAM + " not specified.");
}
if (params.get(PROTO_PARAM).getIntValue() == null) {
- throw new IllegalArgumentException("Classifier: {" + this.getClassDef().getName()
- + "}+ Value of proto parameter is not present.");
+ throw new IllegalArgumentException("Value of " + PROTO_PARAM + " parameter is not present.");
}
}
private void equalOrNotSetValidation(Short protoInMatch, long paramValue) {
if (protoInMatch != null) {
if (paramValue != protoInMatch.longValue()) {
- throw new IllegalArgumentException("Classification conflict at " + this.getClassDef().getName()
- + ": Trying to override proto value: " + protoInMatch.shortValue() + " by value " + paramValue);
+ throw new IllegalArgumentException("Classification conflict detected at " + PROTO_PARAM
+ + " parameter for values " + protoInMatch.shortValue() + " and " + paramValue
+ + ". It is not allowed "
+ + "to assign different values to the same parameter among all the classifiers within one rule.");
}
}
}
try {
readEthType = match.getEthernetMatch().getEthernetType().getType().getValue();
} catch (NullPointerException e) {
- throw new IllegalArgumentException("Ether-type match is missing.");
+ throw new IllegalArgumentException("Parameter " + EtherTypeClassifier.ETHERTYPE_PARAM + " is missing.");
}
if (!FlowUtils.IPv4.equals(readEthType) && !FlowUtils.IPv6.equals(readEthType)) {
- throw new IllegalArgumentException("Ether-type value should be " + FlowUtils.IPv4 + " or "
- + FlowUtils.IPv6 + ".");
+ throw new IllegalArgumentException("Parameter " + EtherTypeClassifier.ETHERTYPE_PARAM + " must have value "
+ + FlowUtils.IPv4 + " or " + FlowUtils.IPv6 + ".");
}
}
}
@Override
protected void checkPresenceOfRequiredParams(Map<String, ParameterValue> params) {
if (params.get(SRC_PORT_PARAM) != null && params.get(SRC_PORT_RANGE_PARAM) != null) {
- throw new IllegalArgumentException("Classifier: {" + this.getClassDef().getName()
- + "}+. Illegal source port parameters: 'int' and 'range' values are mutually exclusive.");
+ throw new IllegalArgumentException("Source port parameters " + SRC_PORT_PARAM + " and " + SRC_PORT_RANGE_PARAM
+ + " are mutually exclusive.");
}
if (params.get(DST_PORT_PARAM) != null && params.get(DST_PORT_RANGE_PARAM) != null) {
- throw new IllegalArgumentException("Classifier: {" + this.getClassDef().getName()
- + "}+. Illegal destination port parameters: 'int' and 'range' values are mutually exclusive.");
+ throw new IllegalArgumentException("Destination port parameters " + DST_PORT_PARAM + " and " + DST_PORT_RANGE_PARAM
+ + " are mutually exclusive.");
}
if (params.get(SRC_PORT_PARAM) != null) {
if (params.get(SRC_PORT_PARAM).getIntValue() == null) {
- throw new IllegalArgumentException("Classifier: {" + this.getClassDef().getName()
- + "}+ Value of sourceport parameter is not present.");
+ throw new IllegalArgumentException("Value of " + SRC_PORT_PARAM + " parameter is not specified.");
}
}
if (params.get(SRC_PORT_RANGE_PARAM) != null) {
if (params.get(DST_PORT_PARAM) != null) {
if (params.get(DST_PORT_PARAM).getIntValue() == null) {
- throw new IllegalArgumentException("Classifier: {" + this.getClassDef().getName()
- + "}+ Value of destport parameter is not present.");
+ throw new IllegalArgumentException("Value of " + DST_PORT_PARAM + " parameter is not specified.");
}
}
if (params.get(DST_PORT_RANGE_PARAM) != null) {
private void validateRangeValue(RangeValue rangeValueParam) {
if (rangeValueParam == null) {
- throw new IllegalArgumentException("Classifier: {" + this.getClassDef().getName()
- + "}+ Range value is not present.");
+ throw new IllegalArgumentException("Range parameter is specifiet but value is not present.");
}
final Long min = rangeValueParam.getMin();
final Long max = rangeValueParam.getMax();
if (min > max) {
- throw new IllegalArgumentException("Range value mismatch. MIN {" + min + "} is greater than MAX {" + max
- + "}.");
+ throw new IllegalArgumentException("Range value mismatch. " + min + " is greater than MAX " + max + ".");
}
}
private Layer4Match resolveL4Match(Map<String, ParameterValue> params) {
Long ipProto = IpProtoClassifier.getIpProtoValue(params);
if (ipProto == null) {
- throw new IllegalArgumentException("Classifier-instance " + this.getClassDef().getName()
- + ": L4 protocol is null.");
+ throw new IllegalArgumentException("Parameter " + IpProtoClassifier.PROTO_PARAM + " is missing.");
}
if (IpProtoClassifier.UDP_VALUE.equals(ipProto)) {
return new UdpMatchBuilder().build();
} else if (IpProtoClassifier.SCTP_VALUE.equals(ipProto)) {
return new SctpMatchBuilder().build();
}
- throw new IllegalArgumentException("Unsupported L4 protocol.");
+ throw new IllegalArgumentException("Parameter " + IpProtoClassifier.PROTO_PARAM + ": value " + ipProto
+ + " is not supported.");
}
private Set<Long> createSetFromRange(RangeValue rangeValueParam) {
private void equalOrNotSetValidation(PortNumber portInMatch, long paramValue) {
if (portInMatch != null) {
if (paramValue != portInMatch.getValue().longValue()) {
- throw new IllegalArgumentException("Classification conflict at " + this.getClassDef().getName()
- + ": Trying to override port value: " + portInMatch.getValue().longValue() + " by value "
- + paramValue);
+ throw new IllegalArgumentException("Classification conflict detected for port values "
+ + portInMatch.getValue().longValue() + " and " + paramValue + ". It is not allowed "
+ + "to assign different values to the same parameter among all the classifiers within one rule.");
}
}
}
try {
proto = Long.valueOf(match.getIpMatch().getIpProtocol().longValue());
} catch (NullPointerException e) {
- throw new IllegalArgumentException("Ip proto match is missing.");
+ throw new IllegalArgumentException("Parameter " + IpProtoClassifier.PROTO_PARAM + " is missing.");
}
if (!IpProtoClassifier.TCP_VALUE.equals(proto) && !IpProtoClassifier.UDP_VALUE.equals(proto)
&& !IpProtoClassifier.SCTP_VALUE.equals(proto)) {
- throw new IllegalArgumentException("Unsupported proto value.\n" + "Classifier: "
- + this.getClass().getName() + ", proto set: " + proto);
+ throw new IllegalArgumentException("Value of parameter " + IpProtoClassifier.PROTO_PARAM
+ + " is not supported.");
}
}
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Matcher.MatchType;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.action.refs.ActionRefBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.condition.matchers.ConditionMatcherBuilder;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.conditions.Condition;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.conditions.ConditionBuilder;\r
Rule rule1 = new RuleBuilder().setActionRef(\r
ImmutableList.of(new ActionRefBuilder().setName(new ActionName("allow")).build()))\r
.setClassifierRef(\r
- createClassifierRefs(ImmutableMap.<String, Direction>of("tcp_dst_80", Direction.In, "tcp_src_80",\r
- Direction.In)))\r
+ createClassifierRefs(ImmutableMap.<String, Direction>of("tcp_dst_80", Direction.In,\r
+ "tcp_src_80", Direction.In)))\r
.build();\r
Rule rule2 = new RuleBuilder().setActionRef(\r
ImmutableList.of(new ActionRefBuilder().setName(new ActionName("allow")).build()))\r
.setClassifierRef(\r
- createClassifierRefs(ImmutableMap.<String, Direction>of("tcp_dst_80", Direction.In, "tcp_src_80",\r
- Direction.Out)))\r
+ createClassifierRefs(ImmutableMap.<String, Direction>of("tcp_dst_80", Direction.In,\r
+ "tcp_src_80", Direction.Out)))\r
.build();\r
Rule rule3 = new RuleBuilder().setActionRef(\r
ImmutableList.of(new ActionRefBuilder().setName(new ActionName("allow")).build()))\r
.setClassifierRef(\r
- createClassifierRefs(ImmutableMap.<String, Direction>of("tcp_dst_80", Direction.In, "tcp_src_80",\r
- Direction.Out, "ether_type", Direction.In)))\r
+ createClassifierRefs(ImmutableMap.<String, Direction>of("tcp_dst_80", Direction.In,\r
+ "tcp_src_80", Direction.Out,\r
+ "ether_type", Direction.In)))\r
.build();\r
+ Rule rule4 = new RuleBuilder().setActionRef(\r
+ ImmutableList.of(new ActionRefBuilder().setName(new ActionName("allow")).build()))\r
+ .setClassifierRef(\r
+ createClassifierRefs(ImmutableMap.<String, Direction>of("tcp_dst_80", Direction.In,\r
+ "tcp_dst_90", Direction.In)))\r
+ .build();\r
+\r
assertEquals(5,\r
doTestDifferentEg(ImmutableList.<Subject>of(createSubject("s1", ImmutableList.<Rule>of(rule1)))));\r
assertEquals(7,\r
doTestDifferentEg(ImmutableList.<Subject>of(createSubject("s2", ImmutableList.<Rule>of(rule2)))));\r
assertEquals(6,\r
doTestDifferentEg(ImmutableList.<Subject>of(createSubject("s3", ImmutableList.<Rule>of(rule3)))));\r
+ assertEquals(3,\r
+ doTestDifferentEg(ImmutableList.<Subject>of(createSubject("s4", ImmutableList.<Rule>of(rule4)))));\r
}\r
\r
private int doTestDifferentEg(List<Subject> subjects) throws Exception {\r
.setIpMatch(ClassifierTestUtils.createIpMatch(ClassifierTestUtils.SCTP.shortValue())));
params.putAll(ClassifierTestUtils.createIntValueParam(EtherTypeClassifier.ETHERTYPE_PARAM, FlowUtils.IPv6));
thrown.expect(IllegalArgumentException.class);
- thrown.expectMessage("Trying to override ether-type value:");
+ thrown.expectMessage("Classification conflict detected");
matches = Classifier.ETHER_TYPE_CL.update(matches, params);
}
public void checkPresenceOfRequiredParameters1Test() {
params.putAll(ClassifierTestUtils.createIntValueParam(IpProtoClassifier.PROTO_PARAM, ClassifierTestUtils.TCP));
thrown.expect(IllegalArgumentException.class);
- thrown.expectMessage("Parameter ethertype not present");
+ thrown.expectMessage("not specified.");
Classifier.ETHER_TYPE_CL.checkPresenceOfRequiredParams(params);
}
.setIpMatch(ClassifierTestUtils.createIpMatch(ClassifierTestUtils.SCTP.shortValue())));
params.putAll(ClassifierTestUtils.createIntValueParam(IpProtoClassifier.PROTO_PARAM, ClassifierTestUtils.TCP));
thrown.expect(IllegalArgumentException.class);
- thrown.expectMessage("Trying to override proto value");
+ thrown.expectMessage("Classification conflict detected");
matches = Classifier.IP_PROTO_CL.update(matches, params);
}
public void checkPresenceOfRequiredParameters1Test() {
params.putAll(ClassifierTestUtils.createIntValueParam(EtherTypeClassifier.ETHERTYPE_PARAM, FlowUtils.IPv4));
thrown.expect(IllegalArgumentException.class);
- thrown.expectMessage("Parameter proto not present");
+ thrown.expectMessage("not specified");
Classifier.IP_PROTO_CL.checkPresenceOfRequiredParams(params);
}
params.putAll(ClassifierTestUtils.createIntValueParam(L4Classifier.SRC_PORT_PARAM, srcPort));
params.putAll(ClassifierTestUtils.createRangeValueParam(L4Classifier.SRC_PORT_RANGE_PARAM, srcRangeStart, srcRangeEnd));
thrown.expect(IllegalArgumentException.class);
- thrown.expectMessage("Illegal source port parameters");
+ thrown.expectMessage("mutually exclusive");
Classifier.L4_CL.checkPresenceOfRequiredParams(params);
}
params.putAll(ClassifierTestUtils.createIntValueParam(L4Classifier.DST_PORT_PARAM, dstPort));
params.putAll(ClassifierTestUtils.createRangeValueParam(L4Classifier.DST_PORT_RANGE_PARAM, dstRangeStart, dstRangeEnd));
thrown.expect(IllegalArgumentException.class);
- thrown.expectMessage("Illegal destination port parameters");
+ thrown.expectMessage("mutually exclusive");
Classifier.L4_CL.checkPresenceOfRequiredParams(params);
}
params.putAll(ClassifierTestUtils.createIntValueParam(IpProtoClassifier.PROTO_PARAM, 136));
params.putAll(ClassifierTestUtils.createRangeValueParam(L4Classifier.DST_PORT_RANGE_PARAM, dstRangeStart, dstRangeEnd));
thrown.expect(IllegalArgumentException.class);
- thrown.expectMessage("Unsupported L4 protocol.");
+ thrown.expectMessage("not supported");
matches = Classifier.L4_CL.update(matches, params);
}
Long dstRangeEnd = Long.valueOf(8081);
params.putAll(ClassifierTestUtils.createRangeValueParam(L4Classifier.DST_PORT_RANGE_PARAM, dstRangeStart, dstRangeEnd));
thrown.expect(IllegalArgumentException.class);
- thrown.expectMessage("L4 protocol is null.");
+ thrown.expectMessage(IpProtoClassifier.PROTO_PARAM + " is missing");
matches = Classifier.L4_CL.update(matches, params);
}
params.putAll(ImmutableMap.<String, ParameterValue> of(L4Classifier.SRC_PORT_PARAM,
new ParameterValueBuilder().build()));
thrown.expect(IllegalArgumentException.class);
- thrown.expectMessage("Value of sourceport parameter is not present");
+ thrown.expectMessage("not specified");
Classifier.L4_CL.checkPresenceOfRequiredParams(params);
}
params.putAll(ImmutableMap.<String, ParameterValue> of(L4Classifier.DST_PORT_PARAM,
new ParameterValueBuilder().build()));
thrown.expect(IllegalArgumentException.class);
- thrown.expectMessage("Value of destport parameter is not present");
+ thrown.expectMessage("not specified");
Classifier.L4_CL.checkPresenceOfRequiredParams(params);
}
params.putAll(ImmutableMap.<String, ParameterValue> of(L4Classifier.SRC_PORT_RANGE_PARAM,
new ParameterValueBuilder().build()));
thrown.expect(IllegalArgumentException.class);
- thrown.expectMessage("Range value is not present");
+ thrown.expectMessage("not present");
Classifier.L4_CL.checkPresenceOfRequiredParams(params);
}
params.putAll(ImmutableMap.<String, ParameterValue> of(L4Classifier.DST_PORT_RANGE_PARAM,
new ParameterValueBuilder().build()));
thrown.expect(IllegalArgumentException.class);
- thrown.expectMessage("Range value is not present");
+ thrown.expectMessage("not present");
Classifier.L4_CL.checkPresenceOfRequiredParams(params);
}