Update MRI projects for Aluminium
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / util / MatchUtil.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 package org.opendaylight.openflowplugin.impl.util;
9
10 import com.google.common.collect.ImmutableMap;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.Optional;
14 import java.util.function.Function;
15 import java.util.stream.Collectors;
16 import org.eclipse.jdt.annotation.NonNull;
17 import org.eclipse.jdt.annotation.Nullable;
18 import org.opendaylight.openflowplugin.openflow.md.core.extension.ExtensionResolvers;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetField;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowWildcardsV10;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10Builder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlowBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlowWriteActionsSetField;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlowWriteActionsSetFieldBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNotifPacketIn;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNotifPacketInBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNotifSwitchFlowRemoved;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNotifSwitchFlowRemovedBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNotifUpdateFlowStats;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchPacketInMessage;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchPacketInMessageBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
38
39 public final class MatchUtil {
40
41     private static final MacAddress ZERO_MAC_ADDRESS = new MacAddress("00:00:00:00:00:00");
42     private static final Ipv4Address ZERO_IPV4_ADDRESS = new Ipv4Address("0.0.0.0");
43
44     private static final Map<Class<? extends Match>, Function<Match, Match>> TRANSFORMERS = ImmutableMap
45             .<Class<? extends Match>, Function<Match, Match>>builder()
46             .put(SetField.class, match -> {
47                 final SetFieldBuilder matchBuilder = new SetFieldBuilder(match);
48
49                 resolveExtensions(match).ifPresent(extensionLists -> matchBuilder
50                         .addAugmentation(GeneralAugMatchNodesNodeTableFlowWriteActionsSetField.class,
51                                 new GeneralAugMatchNodesNodeTableFlowWriteActionsSetFieldBuilder()
52                                         .setExtensionList(extensionLists)
53                                         .build()));
54
55                 return matchBuilder.build();
56             })
57             .put(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow
58                     .Match.class, (match) -> {
59                     final MatchBuilder matchBuilder = new MatchBuilder(match);
60
61                     resolveExtensions(match).ifPresent(extensionLists -> matchBuilder
62                             .addAugmentation(GeneralAugMatchNotifUpdateFlowStats.class,
63                                     new GeneralAugMatchNodesNodeTableFlowBuilder()
64                                             .setExtensionList(extensionLists)
65                                             .build()));
66
67                     return matchBuilder.build();
68                 })
69             .put(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.mod.removed
70                     .Match.class, (match) -> {
71                     final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.mod.removed
72                             .MatchBuilder matchBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types
73                             .rev131026.flow.mod.removed.MatchBuilder(match);
74
75                     resolveExtensions(match).ifPresent(extensionLists -> matchBuilder
76                             .addAugmentation(GeneralAugMatchNotifSwitchFlowRemoved.class,
77                                     new GeneralAugMatchNotifSwitchFlowRemovedBuilder()
78                                             .setExtensionList(extensionLists)
79                                             .build()));
80
81                     return matchBuilder.build();
82                 })
83             .put(org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.packet.received
84                     .Match.class, (match) -> {
85                     final org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.packet.received
86                             .MatchBuilder matchBuilder =
87                             new org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service
88                             .rev130709.packet.received.MatchBuilder(match);
89
90                     resolveExtensions(match).ifPresent(extensionLists -> matchBuilder
91                             .addAugmentation(GeneralAugMatchNotifPacketIn.class,
92                                     new GeneralAugMatchNotifPacketInBuilder()
93                                             .setExtensionList(extensionLists)
94                                             .build()));
95
96                     return matchBuilder.build();
97                 })
98             .put(org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.packet.in.message
99                     .Match.class, (match) -> {
100                     final org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.packet.in.message
101                             .MatchBuilder matchBuilder =
102                             new org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service
103                             .rev130709.packet.in.message.MatchBuilder(match);
104
105                     resolveExtensions(match).ifPresent(extensionLists -> matchBuilder
106                             .addAugmentation(GeneralAugMatchPacketInMessage.class,
107                                     new GeneralAugMatchPacketInMessageBuilder()
108                                             .setExtensionList(extensionLists)
109                                             .build()));
110
111                     return matchBuilder.build();
112                 })
113             .build();
114
115     private MatchUtil() {
116         throw new IllegalStateException("This class should not be instantiated.");
117     }
118
119
120     public static MatchV10Builder createEmptyV10Match() {
121         Short zeroShort = 0;
122         Integer zeroInteger = 0;
123         MatchV10Builder matchV10Builder = new MatchV10Builder();
124         matchV10Builder.setDlDst(ZERO_MAC_ADDRESS);
125         matchV10Builder.setDlSrc(ZERO_MAC_ADDRESS);
126         matchV10Builder.setDlType(zeroInteger);
127         matchV10Builder.setDlVlan(zeroInteger);
128         matchV10Builder.setDlVlanPcp(zeroShort);
129         matchV10Builder.setInPort(zeroInteger);
130         matchV10Builder.setNwDst(ZERO_IPV4_ADDRESS);
131         matchV10Builder.setNwDstMask(zeroShort);
132         matchV10Builder.setNwProto(zeroShort);
133         matchV10Builder.setNwSrc(ZERO_IPV4_ADDRESS);
134         matchV10Builder.setNwSrcMask(zeroShort);
135         matchV10Builder.setNwTos(zeroShort);
136         matchV10Builder.setTpDst(zeroInteger);
137         matchV10Builder.setTpSrc(zeroInteger);
138         FlowWildcardsV10 flowWildcardsV10 =
139                 new FlowWildcardsV10(true, true, true, true, true, true, true, true, true, true);
140         matchV10Builder.setWildcards(flowWildcardsV10);
141         return matchV10Builder;
142     }
143
144     @Nullable
145     public static <T extends Match> T transformMatch(@Nullable final Match match,
146                                                      @NonNull final Class<T> implementedInterface) {
147         if (match == null) {
148             return null;
149         }
150
151         if (implementedInterface.equals(match.implementedInterface())) {
152             return implementedInterface.cast(match);
153         }
154
155         final Function<Match, Match> matchMatchFunction = TRANSFORMERS.get(implementedInterface);
156         return matchMatchFunction == null ? null : implementedInterface.cast(matchMatchFunction.apply(match));
157     }
158
159     private static Optional<List<ExtensionList>> resolveExtensions(final Match match) {
160         return ExtensionResolvers
161                 .getMatchExtensionResolver()
162                 .getExtension(match)
163                 .flatMap(matchExtension ->
164                         Optional.ofNullable(matchExtension.nonnullExtensionList().values()
165                         .stream().collect(Collectors.toList())));
166     }
167 }