05f18c2396c95af670f3237b4f8b6b566c8e49e9
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / registry / flow / FlowRegistryKeyFactory.java
1 /*
2  * Copyright (c) 2015 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.openflowplugin.impl.registry.flow;
10
11 import com.google.common.base.MoreObjects;
12 import com.google.common.base.Preconditions;
13 import java.util.Objects;
14 import org.eclipse.jdt.annotation.NonNull;
15 import org.opendaylight.openflowplugin.api.OFConstants;
16 import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey;
17 import org.opendaylight.openflowplugin.impl.util.MatchNormalizationUtil;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
22 import org.opendaylight.yangtools.yang.common.Uint16;
23 import org.opendaylight.yangtools.yang.common.Uint64;
24 import org.opendaylight.yangtools.yang.common.Uint8;
25
26 public final class FlowRegistryKeyFactory {
27
28     private FlowRegistryKeyFactory() {
29         // Hide implicit constructor
30     }
31
32     @NonNull
33     public static FlowRegistryKey create(final short version, @NonNull final Flow flow) {
34         //TODO: mandatory flow input values (or default values) should be specified via yang model
35         final Uint8 tableId = Preconditions.checkNotNull(flow.getTableId(), "flow tableId must not be null");
36         final Uint16 priority = MoreObjects.firstNonNull(flow.getPriority(), OFConstants.DEFAULT_FLOW_PRIORITY);
37         final Uint64 cookie =
38                 MoreObjects.firstNonNull(flow.getCookie(), OFConstants.DEFAULT_FLOW_COOKIE).getValue();
39         Match match = MatchNormalizationUtil
40                 .normalizeMatch(MoreObjects.firstNonNull(flow.getMatch(), OFConstants.EMPTY_MATCH), version);
41         return new FlowRegistryKeyDto(tableId.toJava(), priority.toJava(), cookie, match);
42     }
43
44     private static final class FlowRegistryKeyDto implements FlowRegistryKey {
45         private final short tableId;
46         private final int priority;
47         private final Uint64 cookie;
48         private final Match match;
49
50         private FlowRegistryKeyDto(final short tableId,
51                                    final int priority,
52                                    @NonNull final Uint64 cookie,
53                                    @NonNull final Match match) {
54             this.tableId = tableId;
55             this.priority = priority;
56             this.cookie = cookie;
57             this.match = match;
58         }
59
60         @Override
61         public boolean equals(final Object object) {
62             if (this == object) {
63                 return true;
64             }
65
66             if (object == null || !(object instanceof FlowRegistryKey)) {
67                 return false;
68             }
69
70             final FlowRegistryKey that = (FlowRegistryKey) object;
71
72             return getPriority() == that.getPriority()
73                     && getTableId() == that.getTableId()
74                     && getCookie().equals(that.getCookie())
75                     && equalMatch(that.getMatch());
76         }
77
78         private boolean equalMatch(final Match input) {
79             GeneralAugMatchNodesNodeTableFlow thisAug = match.augmentation(GeneralAugMatchNodesNodeTableFlow.class);
80             GeneralAugMatchNodesNodeTableFlow inputAug = input.augmentation(GeneralAugMatchNodesNodeTableFlow.class);
81             if (thisAug != inputAug) {
82                 if (thisAug != null) {
83                     if (inputAug == null) {
84                         return false;
85                     }
86                     if (!Objects.equals(match.getEthernetMatch(), input.getEthernetMatch())) {
87                         return false;
88                     }
89                     if (!Objects.equals(match.getIcmpv4Match(), input.getIcmpv4Match())) {
90                         return false;
91                     }
92                     if (!Objects.equals(match.getIcmpv6Match(), input.getIcmpv6Match())) {
93                         return false;
94                     }
95                     if (!Objects.equals(match.getInPhyPort(), input.getInPhyPort())) {
96                         return false;
97                     }
98                     if (!Objects.equals(match.getInPort(), input.getInPort())) {
99                         return false;
100                     }
101                     if (!Objects.equals(match.getIpMatch(), input.getIpMatch())) {
102                         return false;
103                     }
104                     if (!Objects.equals(match.getLayer3Match(), input.getLayer3Match())) {
105                         return false;
106                     }
107                     if (!Objects.equals(match.getLayer4Match(), input.getLayer4Match())) {
108                         return false;
109                     }
110                     if (!Objects.equals(match.getMetadata(), input.getMetadata())) {
111                         return false;
112                     }
113                     if (!Objects.equals(match.getProtocolMatchFields(), input.getProtocolMatchFields())) {
114                         return false;
115                     }
116                     if (!Objects.equals(match.getTcpFlagsMatch(), input.getTcpFlagsMatch())) {
117                         return false;
118                     }
119                     if (!Objects.equals(match.getTunnel(), input.getTunnel())) {
120                         return false;
121                     }
122                     if (!Objects.equals(match.getVlanMatch(), input.getVlanMatch())) {
123                         return false;
124                     }
125                     for (ExtensionList inputExtensionList : inputAug.getExtensionList()) {
126                         if (!thisAug.getExtensionList().contains(inputExtensionList)) {
127                             return false;
128                         }
129                     }
130                 }
131             } else {
132                 return getMatch().equals(input);
133             }
134             return true;
135         }
136
137         @Override
138         public int hashCode() {
139             int result = tableId;
140             result = 31 * result + priority;
141             result = 31 * result + cookie.hashCode();
142             result = 31 * result + match.hashCode();
143             return result;
144         }
145
146         @Override
147         public String toString() {
148             return "FlowRegistryKeyDto{"
149                     + "tableId=" + tableId
150                     + ", priority=" + priority
151                     + ", cookie=" + cookie
152                     + ", match=" + match
153                     + '}';
154         }
155
156         @Override
157         public short getTableId() {
158             return tableId;
159         }
160
161         @Override
162         public int getPriority() {
163             return priority;
164         }
165
166         @Override
167         public Uint64 getCookie() {
168             return cookie;
169         }
170
171         @Override
172         public Match getMatch() {
173             return match;
174         }
175     }
176 }