Bug 3244 - SFC Improvements for distributed classifier, robustness
[groupbasedpolicy.git] / renderers / ofoverlay / src / main / java / org / opendaylight / groupbasedpolicy / renderer / ofoverlay / flow / FlowIdUtils.java
1 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
2
3 import com.google.common.base.Joiner;
4 import com.google.common.base.Strings;
5
6 import org.apache.commons.lang3.StringUtils;
7 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
8 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
9 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
10 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.Extension;
11 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
12 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlow;
13
14 import java.util.Comparator;
15 import java.util.TreeSet;
16
17 public class FlowIdUtils {
18
19     private static final String TABLE_ID_PREFIX = "t";
20     private static final String FLOWID_SEPARATOR = "|";
21     private static final String MATCH_PREFIX = "match[";
22     private static final String MATCH_SUFFIX = "]";
23     private static final String MATCH_SEPARATOR = ", ";
24
25     // *** flow from FlowTable (abstract parent) ***
26
27     /**
28      * For flow without match specified (actually, only "drop all" flow)
29      *
30      * @param prefix String
31      * @return FlowId
32      */
33     public static FlowId newFlowId(String prefix) {
34
35         return new FlowId(prefix);
36     }
37
38     /**
39      * FlowId based on match (with prefix like "t2|localL3|")
40      *
41      * @param tableId Short
42      * @param prefix String
43      * @param match Match
44      * @return FlowId
45      */
46     public static FlowId newFlowId(Short tableId, String prefix, Match match) {
47
48         return new FlowId((tableId != null ? TABLE_ID_PREFIX + tableId + FLOWID_SEPARATOR : "")
49                 + prefix + FLOWID_SEPARATOR
50                 + formatMatch(match));
51     }
52
53     private static String formatMatch(Match match) {
54         if (match == null) {
55             return StringUtils.EMPTY;
56         }
57         StringBuilder builder = new StringBuilder(MATCH_PREFIX);
58         boolean first = true;
59         if (match.getEthernetMatch() != null) {
60             if (first) {
61                 first = false;
62             } else {
63                 builder.append(MATCH_SEPARATOR);
64             }
65             builder.append(match.getEthernetMatch());
66         }
67         if (match.getIcmpv4Match() != null) {
68             if (first) {
69                 first = false;
70             } else {
71                 builder.append(MATCH_SEPARATOR);
72             }
73             builder.append(match.getIcmpv4Match());
74         }
75         if (match.getIcmpv6Match() != null) {
76             if (first) {
77                 first = false;
78             } else {
79                 builder.append(MATCH_SEPARATOR);
80             }
81             builder.append(match.getIcmpv6Match());
82         }
83         if (match.getInPhyPort() != null) {
84             if (first) {
85                 first = false;
86             } else {
87                 builder.append(MATCH_SEPARATOR);
88             }
89             builder.append("inPhyPort=").append(match.getInPhyPort());
90         }
91         if (match.getInPort() != null) {
92             if (first) {
93                 first = false;
94             } else {
95                 builder.append(MATCH_SEPARATOR);
96             }
97             builder.append("inPort=").append(match.getInPort());
98         }
99         if (match.getIpMatch() != null) {
100             if (first) {
101                 first = false;
102             } else {
103                 builder.append(MATCH_SEPARATOR);
104             }
105             builder.append(match.getIpMatch());
106         }
107         if (match.getLayer3Match() != null) {
108             if (first) {
109                 first = false;
110             } else {
111                 builder.append(MATCH_SEPARATOR);
112             }
113             builder.append(match.getLayer3Match());
114         }
115         if (match.getLayer4Match() != null) {
116             if (first) {
117                 first = false;
118             } else {
119                 builder.append(MATCH_SEPARATOR);
120             }
121             builder.append(match.getLayer4Match());
122         }
123         if (match.getMetadata() != null) {
124             if (first) {
125                 first = false;
126             } else {
127                 builder.append(MATCH_SEPARATOR);
128             }
129             builder.append(match.getMetadata());
130         }
131         if (match.getProtocolMatchFields() != null) {
132             if (first) {
133                 first = false;
134             } else {
135                 builder.append(MATCH_SEPARATOR);
136             }
137             builder.append(match.getProtocolMatchFields());
138         }
139         if (match.getTcpFlagMatch() != null) {
140             if (first) {
141                 first = false;
142             } else {
143                 builder.append(MATCH_SEPARATOR);
144             }
145             builder.append(match.getTcpFlagMatch());
146         }
147         if (match.getTunnel() != null) {
148             if (first) {
149                 first = false;
150             } else {
151                 builder.append(MATCH_SEPARATOR);
152             }
153             builder.append(match.getTunnel());
154         }
155         if (match.getVlanMatch() != null) {
156             if (first) {
157                 first = false;
158             } else {
159                 builder.append(MATCH_SEPARATOR);
160             }
161             builder.append(match.getVlanMatch());
162         }
163
164         // only one augmentation is used in Match at the moment;
165         // if in the future there will be more of them, similar handling has to be implemented
166         GeneralAugMatchNodesNodeTableFlow generalAug = match.getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);
167         if(generalAug != null && generalAug.getExtensionList() != null) {
168             TreeSet<String> extensionAugmentationStrings = new TreeSet<>(new Comparator<String>() {
169                 @Override
170                 public int compare(String a, String b) {
171                     return Strings.nullToEmpty(a).compareTo(Strings.nullToEmpty(b));
172                 }
173             });
174             for (ExtensionList e : generalAug.getExtensionList()) {
175                 Extension ext = e.getExtension();
176                 // only one augmentation is used in Extension at the moment;
177                 // if in the future there will be more of them, similar handling has to be implemented,
178                 // probing augmentations one by one and adding their toString results to our TreeSet
179                 // (and every List<> in them needs to be cast to Set<> to avoid non-equivalence
180                 // due to different element order, and possible element duplication)
181                 NxAugMatchNodesNodeTableFlow nxAug = ext.getAugmentation(NxAugMatchNodesNodeTableFlow.class);
182                 if (nxAug != null) {
183                     extensionAugmentationStrings.add(nxAug.toString());
184                 }
185             }
186
187             if (!first) {
188                 builder.append(MATCH_SEPARATOR);
189             }
190             builder.append("GeneralAugMatchNodesNodeTableFlow[<ExtensionList>=")
191                     .append(Joiner.on(", ").skipNulls().join(extensionAugmentationStrings))
192                     .append(']');
193         }
194         builder.append(MATCH_SUFFIX);
195
196         return builder.toString();
197     }
198
199 }