2 * Copyright (c) 2013, 2015 IBM Corporation and others. All rights reserved.
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
9 package org.opendaylight.openflowplugin.impl.util;
11 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
13 import java.util.ArrayList;
14 import java.util.Collection;
17 * Provides comparator for comparing according to various {@link Match} attributes
20 public final class MatchComparatorFactory {
22 private MatchComparatorFactory() {
26 private static final Collection<SimpleComparator<Match>> MATCH_COMPARATORS = new ArrayList<>();
28 MATCH_COMPARATORS.add(MatchComparatorFactory.createEthernet());
29 MATCH_COMPARATORS.add(MatchComparatorFactory.createIcmpv4());
30 MATCH_COMPARATORS.add(MatchComparatorFactory.createInPhyPort());
31 MATCH_COMPARATORS.add(MatchComparatorFactory.createInPort());
32 MATCH_COMPARATORS.add(MatchComparatorFactory.createIp());
33 MATCH_COMPARATORS.add(MatchComparatorFactory.createL3());
34 MATCH_COMPARATORS.add(MatchComparatorFactory.createL4());
35 MATCH_COMPARATORS.add(MatchComparatorFactory.createProtocolMatchFields());
36 MATCH_COMPARATORS.add(MatchComparatorFactory.createMetadata());
37 MATCH_COMPARATORS.add(MatchComparatorFactory.createNull());
38 MATCH_COMPARATORS.add(MatchComparatorFactory.createTunnel());
39 MATCH_COMPARATORS.add(MatchComparatorFactory.createVlan());
42 public static SimpleComparator<Match> createNull() {
43 return new SimpleComparator<Match>() {
45 * Comparation by whole object
48 public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
49 return (statsMatch == null) == (storedMatch == null);
54 public static SimpleComparator<Match> createVlan() {
55 return new SimpleComparator<Match>() {
60 public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
61 if (storedMatch == null) {
64 if (storedMatch.getVlanMatch() == null) {
65 if (statsMatch.getVlanMatch() != null) {
68 } else if (!storedMatch.getVlanMatch().equals(statsMatch.getVlanMatch())) {
76 public static SimpleComparator<Match> createTunnel() {
77 return new SimpleComparator<Match>() {
79 * Comparation by tunnel
82 public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
83 if (storedMatch == null) {
86 if (storedMatch.getTunnel() == null) {
87 if (statsMatch.getTunnel() != null) {
90 } else if (!storedMatch.getTunnel().equals(statsMatch.getTunnel())) {
98 public static SimpleComparator<Match> createProtocolMatchFields() {
99 return new SimpleComparator<Match>() {
101 * Comparation by protocol fields
104 public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
105 if (storedMatch == null) {
108 if (storedMatch.getProtocolMatchFields() == null) {
109 if (statsMatch.getProtocolMatchFields() != null) {
112 } else if (!storedMatch.getProtocolMatchFields().equals(statsMatch.getProtocolMatchFields())) {
120 public static SimpleComparator<Match> createMetadata() {
121 return new SimpleComparator<Match>() {
123 * Comparation by metadata
126 public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
127 if (storedMatch == null) {
130 if (storedMatch.getMetadata() == null) {
131 if (statsMatch.getMetadata() != null) {
134 } else if (!storedMatch.getMetadata().equals(statsMatch.getMetadata())) {
142 public static SimpleComparator<Match> createL4() {
143 return new SimpleComparator<Match>() {
145 * Comparation by layer4
148 public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
149 if (storedMatch == null) {
152 if (storedMatch.getLayer4Match() == null) {
153 if (statsMatch.getLayer4Match() != null) {
156 } else if (!storedMatch.getLayer4Match().equals(statsMatch.getLayer4Match())) {
164 public static SimpleComparator<Match> createL3() {
165 return new SimpleComparator<Match>() {
167 * Comparation by layer3
170 public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
171 if (storedMatch == null) {
174 if (storedMatch.getLayer3Match() == null) {
175 if (statsMatch.getLayer3Match() != null) {
178 } else if (!MatchComparatorHelper.layer3MatchEquals(statsMatch.getLayer3Match(), storedMatch.getLayer3Match())) {
186 public static SimpleComparator<Match> createIp() {
187 return new SimpleComparator<Match>() {
192 public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
193 if (storedMatch == null) {
196 if (storedMatch.getIpMatch() == null) {
197 if (statsMatch.getIpMatch() != null) {
200 } else if (!storedMatch.getIpMatch().equals(statsMatch.getIpMatch())) {
208 public static SimpleComparator<Match> createInPort() {
209 return new SimpleComparator<Match>() {
211 * Comparation by InPort
214 public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
215 if (storedMatch == null) {
218 if (storedMatch.getInPort() == null) {
219 if (statsMatch.getInPort() != null) {
222 } else if (!storedMatch.getInPort().equals(statsMatch.getInPort())) {
230 public static SimpleComparator<Match> createInPhyPort() {
231 return new SimpleComparator<Match>() {
233 * Comparation by InPhyPort
236 public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
237 if (storedMatch == null) {
240 if (storedMatch.getInPhyPort() == null) {
241 if (statsMatch.getInPhyPort() != null) {
244 } else if (!storedMatch.getInPhyPort().equals(statsMatch.getInPhyPort())) {
252 public static SimpleComparator<Match> createEthernet() {
253 return new SimpleComparator<Match>() {
255 * Comparation by Ethernet
258 public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
259 if (storedMatch == null) {
262 if (storedMatch.getEthernetMatch() == null) {
263 if (statsMatch.getEthernetMatch() != null) {
266 } else if (!MatchComparatorHelper.ethernetMatchEquals(statsMatch.getEthernetMatch(), storedMatch.getEthernetMatch())) {
274 public static SimpleComparator<Match> createIcmpv4() {
275 return new SimpleComparator<Match>() {
277 * Comparation by Icmpv4
280 public boolean areObjectsEqual(Match statsMatch, Match storedMatch) {
281 if (storedMatch == null) {
284 if (storedMatch.getIcmpv4Match() == null) {
285 if (statsMatch.getIcmpv4Match() != null) {
288 } else if (!storedMatch.getIcmpv4Match().equals(statsMatch.getIcmpv4Match())) {
296 public static SimpleComparator<Match> createMatch() {
297 return new SimpleComparator<Match>() {
299 * Compares flows by whole match
302 public boolean areObjectsEqual(final Match statsFlow, final Match storedFlow) {
303 if (statsFlow == null) {
304 if (storedFlow != null) {
307 } else if (!compareMatches(statsFlow, storedFlow)) {
317 * Explicit equals method to compare the 'match' for flows stored in the data-stores and flow fetched from the switch.
318 * Flow installation process has three steps
319 * 1) Store flow in config data store
320 * 2) and send it to plugin for installation
321 * 3) Flow gets installed in switch
323 * The flow user wants to install and what finally gets installed in switch can be slightly different.
324 * E.g, If user installs flow with src/dst ip=10.0.0.1/24, when it get installed in the switch
325 * src/dst ip will be changes to 10.0.0.0/24 because of netmask of 24. When statistics manager fetch
326 * stats it gets 10.0.0.0/24 rather then 10.0.0.1/24. Custom match takes care of by using masked ip
327 * while comparing two ip addresses.
329 * Sometimes when user don't provide few values that is required by flow installation request, like
330 * priority,hard timeout, idle timeout, cookies etc, plugin usages default values before sending
331 * request to the switch. So when statistics manager gets flow statistics, it gets the default value.
332 * But the flow stored in config data store don't have those defaults value. I included those checks
333 * in the customer flow/match equal function.
340 private static boolean compareMatches(final Match statsMatch, final Match storedMatch) {
341 if (statsMatch == storedMatch) {
345 for (SimpleComparator<Match> matchComp : MATCH_COMPARATORS) {
346 if (!matchComp.areObjectsEqual(statsMatch, storedMatch)) {