Merge "ONF Bundles sample application"
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / util / MatchUtil.java
index a64bac5eca56e59832f63ca1ea8c2b82c0a59e4e..d6a2c450ece02de262bafa8eca0589251183c399 100644 (file)
@@ -8,18 +8,94 @@
 
 package org.opendaylight.openflowplugin.impl.util;
 
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import com.google.common.collect.ImmutableMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Function;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.openflowplugin.openflow.md.core.extension.ExtensionResolvers;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowWildcardsV10;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNotifPacketIn;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNotifPacketInBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNotifSwitchFlowRemoved;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNotifSwitchFlowRemovedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchPacketInMessage;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchPacketInMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
 
-/**
- * Created by Martin Bobak <mbobak@cisco.com> on 21.4.2015.
- */
 public final class MatchUtil {
 
     private static final MacAddress ZERO_MAC_ADDRESS = new MacAddress("00:00:00:00:00:00");
     private static final Ipv4Address ZERO_IPV4_ADDRESS = new Ipv4Address("0.0.0.0");
+
+    private static final Map<Class<? extends Match>, Function<Match, Match>> TRANSFORMERS = ImmutableMap
+            .<Class<? extends Match>, Function<Match, Match>>builder()
+            .put(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow
+                    .Match.class, (match) -> {
+                final MatchBuilder matchBuilder = new MatchBuilder(match);
+
+                resolveExtensions(match).ifPresent(extensionLists -> matchBuilder
+                        .addAugmentation(GeneralAugMatchNodesNodeTableFlow.class,
+                                new GeneralAugMatchNodesNodeTableFlowBuilder()
+                                        .setExtensionList(extensionLists)
+                                        .build()));
+
+                return matchBuilder.build();
+            })
+            .put(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.mod.removed
+                    .Match.class, (match) -> {
+                final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.mod.removed
+                        .MatchBuilder matchBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types
+                        .rev131026.flow.mod.removed.MatchBuilder(match);
+
+                resolveExtensions(match).ifPresent(extensionLists -> matchBuilder
+                        .addAugmentation(GeneralAugMatchNotifSwitchFlowRemoved.class,
+                                new GeneralAugMatchNotifSwitchFlowRemovedBuilder()
+                                        .setExtensionList(extensionLists)
+                                        .build()));
+
+                return matchBuilder.build();
+            })
+            .put(org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.packet.received
+                    .Match.class, (match) -> {
+                final org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.packet.received
+                        .MatchBuilder matchBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service
+                        .rev130709.packet.received.MatchBuilder(match);
+
+                resolveExtensions(match).ifPresent(extensionLists -> matchBuilder
+                        .addAugmentation(GeneralAugMatchNotifPacketIn.class,
+                                new GeneralAugMatchNotifPacketInBuilder()
+                                        .setExtensionList(extensionLists)
+                                        .build()));
+
+                return matchBuilder.build();
+            })
+            .put(org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.packet.in.message
+                    .Match.class, (match) -> {
+                final org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.packet.in.message
+                        .MatchBuilder matchBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service
+                        .rev130709.packet.in.message.MatchBuilder(match);
+
+                resolveExtensions(match).ifPresent(extensionLists -> matchBuilder
+                        .addAugmentation(GeneralAugMatchPacketInMessage.class,
+                                new GeneralAugMatchPacketInMessageBuilder()
+                                        .setExtensionList(extensionLists)
+                                        .build()));
+
+                return matchBuilder.build();
+            })
+            .build();
+
     private MatchUtil(){
         throw new IllegalStateException("This class should not be instantiated.");
     }
@@ -27,7 +103,7 @@ public final class MatchUtil {
 
     public static MatchV10Builder createEmptyV10Match() {
         Short zeroShort = Short.valueOf("0");
-        Integer zeroInteger = Integer.valueOf(0);
+        Integer zeroInteger = 0;
         MatchV10Builder matchV10Builder = new MatchV10Builder();
         matchV10Builder.setDlDst(ZERO_MAC_ADDRESS);
         matchV10Builder.setDlSrc(ZERO_MAC_ADDRESS);
@@ -43,11 +119,35 @@ public final class MatchUtil {
         matchV10Builder.setNwTos(zeroShort);
         matchV10Builder.setTpDst(zeroInteger);
         matchV10Builder.setTpSrc(zeroInteger);
-        FlowWildcardsV10 flowWildcardsV10 = FlowWildcardsV10.getDefaultInstance("");
+        FlowWildcardsV10 flowWildcardsV10 = new FlowWildcardsV10(true, true, true, true, true, true, true, true, true, true);
         matchV10Builder.setWildcards(flowWildcardsV10);
         return matchV10Builder;
     }
 
+    @Nullable
+    public static <T extends Match> T transformMatch(@Nullable final Match match,
+                                                     @Nonnull final Class<T> implementedInterface) {
+        if (Objects.isNull(match)) {
+            return null;
+        }
+
+        if (implementedInterface.equals(match.getImplementedInterface())) {
+            return implementedInterface.cast(match);
+        }
 
+        final Function<Match, Match> matchMatchFunction = TRANSFORMERS.get(implementedInterface);
 
+        if (Objects.isNull(matchMatchFunction)) {
+            return null;
+        }
+
+        return implementedInterface.cast(matchMatchFunction.apply(match));
+    }
+
+    private static Optional<List<ExtensionList>> resolveExtensions(final Match match) {
+        return ExtensionResolvers
+                .getMatchExtensionResolver()
+                .getExtension(match)
+                .flatMap(matchExtension -> Optional.ofNullable(matchExtension.getExtensionList()));
+    }
 }