Registration point for renderer capabilities
[groupbasedpolicy.git] / renderers / ofoverlay / src / main / java / org / opendaylight / groupbasedpolicy / renderer / ofoverlay / sf / IpProtoClassifier.java
old mode 100644 (file)
new mode 100755 (executable)
index e02f8d0..d1ea4f9
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 
 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf;
 
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
+import com.google.common.collect.ImmutableList;
+import org.opendaylight.groupbasedpolicy.sf.classifiers.IpProtoClassifierDefinition;
+import org.opendaylight.groupbasedpolicy.sf.classifiers.EtherTypeClassifierDefinition;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definition.ParameterBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definition.Parameter.IsRequired;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definition.Parameter.Type;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinition;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinitionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.parameters.type.parameter.type.IntBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.supported.classifier.definition.SupportedParameterValues;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.supported.classifier.definition.SupportedParameterValuesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.supported._int.value.fields.SupportedIntValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.supported._int.value.fields.SupportedIntValueBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
 
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
 /**
  * Match on the IP protocol of IP traffic
  */
-public class IpProtoClassifier extends EtherTypeClassifier {
-    public static final ClassifierDefinitionId ID = 
-            new ClassifierDefinitionId("79c6fdb2-1e1a-4832-af57-c65baf5c2335");
-    protected static final String PROTO = "proto";
-    protected static final ClassifierDefinition DEF = 
-            new ClassifierDefinitionBuilder()
-                .setId(ID)
-                .setParent(EtherTypeClassifier.ID)
-                .setName(new ClassifierName("ip_proto"))
-                .setDescription(new Description("Match on the IP protocol of IP traffic"))
-                .setParameter(ImmutableList.of(new ParameterBuilder()
-                    .setName(new ParameterName(PROTO))
-                    .setDescription(new Description("The IP protocol to match against"))
-                    .setIsRequired(IsRequired.Required)
-                    .setType(Type.Int)
-                    .build()))
-                .build();
+public class IpProtoClassifier extends Classifier {
 
-    private static final Map<String, Object> ipv4 = 
-        ImmutableMap.<String,Object>of(TYPE, FlowUtils.IPv4);
-    private static final Map<String, Object> ipv6 = 
-            ImmutableMap.<String,Object>of(TYPE, FlowUtils.IPv6);
+    protected IpProtoClassifier(Classifier parent) {
+        super(parent);
+    }
 
     @Override
     public ClassifierDefinitionId getId() {
-        return ID;
+        return IpProtoClassifierDefinition.ID;
+    }
+
+    @Override
+    public ClassifierDefinition getClassifierDefinition() {
+        return IpProtoClassifierDefinition.DEFINITION;
     }
 
     @Override
-    public ClassifierDefinition getClassDef() {
-        return DEF;
+    public List<SupportedParameterValues> getSupportedParameterValues() {
+
+        List<SupportedIntValue> values = ImmutableList.of(
+                new SupportedIntValueBuilder().setValue(IpProtoClassifierDefinition.ICMP_VALUE)
+                        .build(),
+                new SupportedIntValueBuilder().setValue(IpProtoClassifierDefinition.SCTP_VALUE)
+                        .build(),
+                new SupportedIntValueBuilder().setValue(IpProtoClassifierDefinition.TCP_VALUE)
+                        .build(),
+                new SupportedIntValueBuilder().setValue(IpProtoClassifierDefinition.UDP_VALUE)
+                        .build());
+        SupportedParameterValuesBuilder b = new SupportedParameterValuesBuilder();
+        b.setParameterName(new ParameterName(IpProtoClassifierDefinition.PROTO_PARAM));
+        b.setParameterType(new IntBuilder().setSupportedIntValue(values).build());
+
+        return ImmutableList.of(b.build());
     }
 
     @Override
-    public List<MatchBuilder> updateMatch(List<MatchBuilder> matches,
-                                          Map<String, Object> params) {
-        Object param = params.get(PROTO);
-        // XXX TODO generate exception and fail the match
-        if (param == null || !(param instanceof Long)) return matches;
-        Long proto = (Long)param;
-        
-        ArrayList<MatchBuilder> r = new ArrayList<>();
-        for (MatchBuilder b : matches) {
-            r.addAll(updateMatch(new MatchBuilder(b.build()), proto, ipv4));
-            r.addAll(updateMatch(new MatchBuilder(b.build()), proto, ipv6));
+    protected void checkPresenceOfRequiredParams(Map<String, ParameterValue> params) {
+        if (params.get(IpProtoClassifierDefinition.PROTO_PARAM) == null) {
+            throw new IllegalArgumentException("Parameter " + IpProtoClassifierDefinition.PROTO_PARAM
+                    + " not specified.");
+        }
+        if (params.get(IpProtoClassifierDefinition.PROTO_PARAM).getIntValue() == null) {
+            throw new IllegalArgumentException("Value of " + IpProtoClassifierDefinition.PROTO_PARAM
+                    + " parameter is not present.");
         }
-        return r;
     }
 
-    private List<MatchBuilder> updateMatch(MatchBuilder match,
-                                           Long proto,
-                                           Map<String, Object> parentParams) {
-        List<MatchBuilder> r = 
-                super.updateMatch(Collections.singletonList(match), 
-                                  parentParams);
-        for (MatchBuilder mb : r) {
+    @Override
+    protected List<MatchBuilder> update(List<MatchBuilder> matches, Map<String, ParameterValue> params) {
+        Long proto = params.get(IpProtoClassifierDefinition.PROTO_PARAM).getIntValue();
+        for (MatchBuilder match : matches) {
             IpMatchBuilder imb;
-            if (mb.getIpMatch() != null)
-                imb = new IpMatchBuilder(mb.getIpMatch());
-            else 
+            if (match.getIpMatch() != null) {
+                equalOrNotSetValidation(match.getIpMatch().getIpProtocol(), proto);
+                continue;
+            } else {
                 imb = new IpMatchBuilder();
+            }
             imb.setIpProtocol(proto.shortValue());
-            mb.setIpMatch(imb.build());
+            match.setIpMatch(imb.build());
+        }
+        return matches;
+    }
+
+    private void equalOrNotSetValidation(Short protoInMatch, long paramValue) {
+        if (protoInMatch != null) {
+            if (paramValue != protoInMatch.longValue()) {
+                throw new IllegalArgumentException("Classification conflict detected at " + IpProtoClassifierDefinition.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.");
+            }
+        }
+    }
+
+    @Override
+    protected void checkPrereqs(List<MatchBuilder> matches) {
+        for (MatchBuilder match : matches) {
+            Long readEthType = null;
+            try {
+                readEthType = match.getEthernetMatch().getEthernetType().getType().getValue();
+            } catch (NullPointerException e) {
+                throw new IllegalArgumentException("Parameter " + EtherTypeClassifierDefinition.ETHERTYPE_PARAM
+                        + " is missing.");
+            }
+            if (!FlowUtils.IPv4.equals(readEthType) && !FlowUtils.IPv6.equals(readEthType)) {
+                throw new IllegalArgumentException("Parameter " + EtherTypeClassifierDefinition.ETHERTYPE_PARAM
+                        + " must have value " + FlowUtils.IPv4 + " or " + FlowUtils.IPv6 + ".");
+            }
+        }
+    }
+
+    /**
+     * Return the IpProtocol value. May return null.
+     * @param params the parameters of classifier-instance inserted by user
+     * @return the IpProtocol value
+     */
+    public static Long getIpProtoValue(Map<String, ParameterValue> params) {
+        if (params == null) {
+            return null;
+        }
+        if (params.get(IpProtoClassifierDefinition.PROTO_PARAM) == null) {
+            return null;
+        }
+        Long proto = params.get(IpProtoClassifierDefinition.PROTO_PARAM).getIntValue();
+        if (proto != null) {
+            return proto;
         }
-        return r;
+        return null;
     }
 }