Classifiers - implementation changes.
[groupbasedpolicy.git] / renderers / ofoverlay / src / main / java / org / opendaylight / groupbasedpolicy / renderer / ofoverlay / sf / Classifier.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.renderer.ofoverlay.sf;
10
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.Map;
14
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinition;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
19
20 import com.google.common.base.Strings;
21
22 /**
23  * Represent a classifier definition, and provide tools for generating flow
24  * rules based on the classifier
25  */
26 public abstract class Classifier {
27
28     protected final Classifier parent;
29
30     public static final EtherTypeClassifier ETHER_TYPE_CL = new EtherTypeClassifier(null);
31     public static final IpProtoClassifier IP_PROTO_CL = new IpProtoClassifier(ETHER_TYPE_CL);
32     public static final L4Classifier L4_CL = new L4Classifier(IP_PROTO_CL);
33
34     protected Classifier(Classifier parent) {
35         this.parent = parent;
36     }
37
38     /**
39      * Get the classifier definition id for this classifier
40      *
41      * @return the {@link ClassifierDefinitionId} for this classifier
42      */
43     public abstract ClassifierDefinitionId getId();
44
45     /**
46      * Get the classifier definition for this classifier
47      *
48      * @return the {@link ClassifierDefinition} for this classifier
49      */
50     public abstract ClassifierDefinition getClassDef();
51
52     /**
53      * @return parent classifier
54      * @see {@link ClassifierDefinition}
55      */
56     public final Classifier getParent() {
57         return parent;
58     }
59
60     /**
61      * Template method for resolving {@code matches}.
62      *
63      * @param matches list of builders containing {@code matches} to update
64      * @param params parameters of classifier-instance inserted by user
65      * @return result, which indicates if all the matching fields were updated successfully and
66      *         contain updated {@code matches}
67      * @see {@link ClassificationResult}
68      */
69     public final ClassificationResult updateMatch(List<MatchBuilder> matches, Map<String, ParameterValue> params) {
70         if (params == null) {
71             return new ClassificationResult("Classifier: {" + this.getClassDef().getName() + "} No parameters present.");
72         }
73         List<MatchBuilder> matchBuilders = matches;
74         try {
75             checkPresenceOfRequiredParams(params);
76             matchBuilders = this.update(matchBuilders, params);
77             Classifier parent = this.getParent();
78             List<Classifier> updatedClassifiers = new ArrayList<>();
79             updatedClassifiers.add(this);
80             while (parent != null) {
81                 boolean hasReqParams = true;
82                 try {
83                     parent.checkPresenceOfRequiredParams(params);
84                 } catch (IllegalArgumentException e) {
85                     hasReqParams = false;
86                 }
87                 if (hasReqParams == true) {
88                     matchBuilders = parent.update(matchBuilders, params);
89                     updatedClassifiers.add(parent);
90                 }
91                 parent = parent.getParent();
92             }
93             for (Classifier updatedClassifier : updatedClassifiers) {
94                 updatedClassifier.checkPrereqs(matchBuilders);
95             }
96         } catch (IllegalArgumentException e) {
97             if (!Strings.isNullOrEmpty(e.getMessage())) {
98                 return new ClassificationResult(e.getMessage());
99             } else
100                 return new ClassificationResult("Error while processing data of " + this.getClassDef().getName()
101                         + " classifier. Classification was not successful.");
102         }
103         return new ClassificationResult(matchBuilders);
104     }
105
106 /**
107      * Checks presence of required {@code params} in order to decide if classifier can update {@code matches} properly
108      * in  method {@link #update(List, Map)
109      * @param  params  inserted parameters, not null
110      * @return  true, if required parameters are present
111      * @throws  IllegalArgumentException when any of required {@code params} is not present
112      * @see  {@link #updateMatch(List, Map)}
113      */
114     protected abstract void checkPresenceOfRequiredParams(Map<String, ParameterValue> params);
115
116     /**
117      * Resolves {@code matches} from inserted {@code params} and updates them.
118      * <p>
119      * Updates fields in {@code matches} or it can creates new matches. If it creates new matches it
120      * has to always use match from {@code matches} as parameter in constructor
121      * {@code MatchBuilder(Match base)}
122      *
123      * @param matches - fields to update
124      * @param params - input parameters
125      * @return updated {@code matches}. It is allowed to return new object.
126      * @throws IllegalArgumentException when update fails because of bad input
127      *         (e.g. overriding existing matches with different values is not permitted)
128      */
129     protected abstract List<MatchBuilder> update(List<MatchBuilder> matches, Map<String, ParameterValue> params);
130
131     /**
132      * Checks whether prerequisites (required {@code matches}) for the match that this classifier
133      * updates are present
134      * according to Openflow specifications.
135      *
136      * @param matches input list of matches to check
137      * @throws IllegalArgumentException when any of prerequisites is not present
138      */
139     protected abstract void checkPrereqs(List<MatchBuilder> matches);
140 }