2 * Copyright (c) 2015 Cisco Systems, Inc. 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
8 package org.opendaylight.openflowplugin.impl.registry.flow;
10 import static java.util.Objects.requireNonNull;
11 import static java.util.Objects.requireNonNullElse;
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.inventory.rev130819.FlowId;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
23 import org.opendaylight.yangtools.yang.common.Uint16;
24 import org.opendaylight.yangtools.yang.common.Uint64;
25 import org.opendaylight.yangtools.yang.common.Uint8;
27 public final class FlowRegistryKeyFactory {
28 // Temporary use, we will overwrite this. We do not have a flow ID and are about to make one up
29 // from the contents -- but for that we need a Flow object. But for that we need a FlowId, but
30 // ... so we set a dummy value and overwrite it afterwards.
31 public static final FlowKey DUMMY_FLOW_KEY = new FlowKey(new FlowId("__DUMMY_ID_FOR_ALIEN__"));
33 private FlowRegistryKeyFactory() {
34 // Hide implicit constructor
37 public static @NonNull FlowRegistryKey create(final Uint8 version, final @NonNull Flow flow) {
38 //TODO: mandatory flow input values (or default values) should be specified via yang model
39 final Uint8 tableId = requireNonNull(flow.getTableId(), "flow tableId must not be null");
40 final Uint16 priority = requireNonNullElse(flow.getPriority(), OFConstants.DEFAULT_FLOW_PRIORITY);
41 final Uint64 cookie = requireNonNullElse(flow.getCookie(), OFConstants.DEFAULT_FLOW_COOKIE).getValue();
42 Match match = MatchNormalizationUtil.normalizeMatch(
43 requireNonNullElse(flow.getMatch(), OFConstants.EMPTY_MATCH), version);
44 return new FlowRegistryKeyDto(tableId.toJava(), priority.toJava(), cookie, match);
47 private static final class FlowRegistryKeyDto implements FlowRegistryKey {
48 private final short tableId;
49 private final int priority;
50 private final Uint64 cookie;
51 private final Match match;
53 private FlowRegistryKeyDto(final short tableId, final int priority, final @NonNull Uint64 cookie,
54 final @NonNull Match match) {
55 this.tableId = tableId;
56 this.priority = priority;
62 public boolean equals(final Object obj) {
63 return this == obj || obj instanceof FlowRegistryKey that
64 && priority == that.getPriority() && tableId == that.getTableId() && cookie.equals(that.getCookie())
65 && equalMatch(that.getMatch());
68 private boolean equalMatch(final Match input) {
69 GeneralAugMatchNodesNodeTableFlow thisAug = match.augmentation(GeneralAugMatchNodesNodeTableFlow.class);
70 GeneralAugMatchNodesNodeTableFlow inputAug = input.augmentation(GeneralAugMatchNodesNodeTableFlow.class);
71 if (thisAug != inputAug) {
72 if (thisAug != null) {
73 if (inputAug == null) {
76 if (!Objects.equals(match.getEthernetMatch(), input.getEthernetMatch())) {
79 if (!Objects.equals(match.getIcmpv4Match(), input.getIcmpv4Match())) {
82 if (!Objects.equals(match.getIcmpv6Match(), input.getIcmpv6Match())) {
85 if (!Objects.equals(match.getInPhyPort(), input.getInPhyPort())) {
88 if (!Objects.equals(match.getInPort(), input.getInPort())) {
91 if (!Objects.equals(match.getIpMatch(), input.getIpMatch())) {
94 if (!Objects.equals(match.getLayer3Match(), input.getLayer3Match())) {
97 if (!Objects.equals(match.getLayer4Match(), input.getLayer4Match())) {
100 if (!Objects.equals(match.getMetadata(), input.getMetadata())) {
103 if (!Objects.equals(match.getProtocolMatchFields(), input.getProtocolMatchFields())) {
106 if (!Objects.equals(match.getTcpFlagsMatch(), input.getTcpFlagsMatch())) {
109 if (!Objects.equals(match.getTunnel(), input.getTunnel())) {
112 if (!Objects.equals(match.getVlanMatch(), input.getVlanMatch())) {
115 for (var inputExtensionList : inputAug.nonnullExtensionList().values()) {
116 if (!thisAug.nonnullExtensionList().containsValue(inputExtensionList)) {
122 return getMatch().equals(input);
128 public int hashCode() {
129 int result = tableId;
130 result = 31 * result + priority;
131 result = 31 * result + cookie.hashCode();
132 result = 31 * result + match.hashCode();
137 public String toString() {
138 return "FlowRegistryKeyDto{"
139 + "tableId=" + tableId
140 + ", priority=" + priority
141 + ", cookie=" + cookie
147 public short getTableId() {
152 public int getPriority() {
157 public Uint64 getCookie() {
162 public Match getMatch() {