7b69f1349e98251690f5449df5c2750b89a5fed2
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / extension / MatchExtensionHelper.java
1 /**
2  * Copyright (c) 2014 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.openflow.md.core.extension;
9
10 import java.util.ArrayList;
11 import java.util.Collection;
12 import java.util.List;
13 import java.util.Objects;
14 import java.util.Optional;
15 import org.opendaylight.openflowjava.protocol.api.keys.MatchEntrySerializerKey;
16 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
17 import org.opendaylight.openflowplugin.extension.api.AugmentTuple;
18 import org.opendaylight.openflowplugin.extension.api.ConvertorFromOFJava;
19 import org.opendaylight.openflowplugin.extension.api.ExtensionAugment;
20 import org.opendaylight.openflowplugin.extension.api.path.MatchPath;
21 import org.opendaylight.openflowplugin.openflow.md.core.session.OFSessionUtil;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmClassBase;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
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.GeneralAugMatchNotifPacketIn;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNotifPacketInBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNotifSwitchFlowRemoved;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNotifSwitchFlowRemovedBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNotifUpdateFlowStats;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNotifUpdateFlowStatsBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchPacketInMessage;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchPacketInMessageBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchRpcOutputFlowStats;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchRpcOutputFlowStatsBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.Extension;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.ExtensionBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionListBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.packet.received.Match;
43 import org.opendaylight.yangtools.yang.binding.Augmentable;
44 import org.opendaylight.yangtools.yang.binding.Augmentation;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 public final class MatchExtensionHelper {
49
50     private static final Logger LOG = LoggerFactory
51             .getLogger(MatchExtensionHelper.class);
52
53     private MatchExtensionHelper() {
54         throw new IllegalAccessError("singleton enforcement");
55     }
56
57
58     /**
59      * @param matchEntry match entry
60      * @param ofVersion openflow version
61      * @param matchPath match path
62      */
63     public static void injectExtension(
64             final short ofVersion,
65             final MatchEntry matchEntry,
66             final MatchBuilder matchBuilder,
67             final MatchPath matchPath) {
68
69         final ExtensionListBuilder extBuilder = processExtension(matchEntry, ofVersion, matchPath);
70
71         if (Objects.isNull(extBuilder)) {
72             LOG.warn("Convertor for {} for version {} with match path {} not found.",
73                     matchEntry.toString(),
74                     ofVersion,
75                     matchPath.name());
76         }
77
78         final GeneralAugMatchNodesNodeTableFlowBuilder builder = Optional
79                 .ofNullable(matchBuilder.getAugmentation(GeneralAugMatchNodesNodeTableFlow.class))
80                 .map(GeneralAugMatchNodesNodeTableFlowBuilder::new)
81                 .orElse(new GeneralAugMatchNodesNodeTableFlowBuilder().setExtensionList(new ArrayList<>()));
82
83         builder.getExtensionList().add(extBuilder.build());
84         matchBuilder.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, builder.build());
85     }
86
87     /**
88      * @param matchEntries match entries
89      * @param ofVersion openflow version
90      * @param matchPath match path
91      * @param <EXT_POINT> extension point
92      * @return augmentation wrapper containing augmentation depending on matchPath
93      */
94     @SuppressWarnings("unchecked")
95     public static <EXT_POINT extends Augmentable<EXT_POINT>>
96     AugmentTuple<EXT_POINT> processAllExtensions(Collection<MatchEntry> matchEntries,
97                                                  OpenflowVersion ofVersion, MatchPath matchPath) {
98         List<ExtensionList> extensionsList = new ArrayList<>();
99
100         for (MatchEntry matchEntry : matchEntries) {
101             ExtensionListBuilder extensionListBld = processExtension(matchEntry, ofVersion.getVersion(), matchPath);
102             if (extensionListBld == null) {
103                 continue;
104             }
105
106             extensionsList.add(extensionListBld.build());
107         }
108
109         AugmentTuple<EXT_POINT> augmentTuple = null;
110         if (!extensionsList.isEmpty()) {
111             switch (matchPath) {
112                 case FLOWSSTATISTICSUPDATE_FLOWANDSTATISTICSMAPLIST_MATCH:
113                     GeneralAugMatchNotifUpdateFlowStatsBuilder generalExtMatchAugBld1 = new GeneralAugMatchNotifUpdateFlowStatsBuilder();
114                     generalExtMatchAugBld1.setExtensionList(extensionsList);
115                     augmentTuple = (AugmentTuple<EXT_POINT>)
116                             new AugmentTuple<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match>(
117                                     GeneralAugMatchNotifUpdateFlowStats.class, generalExtMatchAugBld1.build());
118                     break;
119                 case PACKETRECEIVED_MATCH:
120                     GeneralAugMatchNotifPacketInBuilder generalExtMatchAugBld2 = new GeneralAugMatchNotifPacketInBuilder();
121                     generalExtMatchAugBld2.setExtensionList(extensionsList);
122                     augmentTuple = (AugmentTuple<EXT_POINT>)
123                             new AugmentTuple<Match>(GeneralAugMatchNotifPacketIn.class, generalExtMatchAugBld2.build());
124                     break;
125                 case PACKETINMESSAGE_MATCH:
126                     GeneralAugMatchPacketInMessageBuilder generalExtMatchAugBld5 = new GeneralAugMatchPacketInMessageBuilder();
127                     generalExtMatchAugBld5.setExtensionList(extensionsList);
128                     augmentTuple = (AugmentTuple<EXT_POINT>)
129                             new AugmentTuple<org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.packet.in.message
130                                     .Match>(GeneralAugMatchPacketInMessage.class, generalExtMatchAugBld5.build());
131                     break;
132                 case SWITCHFLOWREMOVED_MATCH:
133                     GeneralAugMatchNotifSwitchFlowRemovedBuilder generalExtMatchAugBld3 = new GeneralAugMatchNotifSwitchFlowRemovedBuilder();
134                     generalExtMatchAugBld3.setExtensionList(extensionsList);
135                     augmentTuple = (AugmentTuple<EXT_POINT>)
136                             new AugmentTuple<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.mod.removed.Match>(
137                                     GeneralAugMatchNotifSwitchFlowRemoved.class, generalExtMatchAugBld3.build());
138                     break;
139                 case RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_MATCH:
140                     GeneralAugMatchRpcOutputFlowStatsBuilder generalExtMatchAugBld4 = new GeneralAugMatchRpcOutputFlowStatsBuilder();
141                     generalExtMatchAugBld4.setExtensionList(extensionsList);
142                     augmentTuple = (AugmentTuple<EXT_POINT>)
143                             new AugmentTuple<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match>(
144                                     GeneralAugMatchRpcOutputFlowStats.class, generalExtMatchAugBld4.build());
145                     break;
146                 default:
147                     LOG.warn("matchPath not supported: {}", matchPath);
148             }
149         }
150
151         return augmentTuple;
152     }
153
154     /**
155      * @param ofVersion
156      * @param matchPath
157      * @param matchEntry
158      * @return
159      */
160     private static ExtensionListBuilder processExtension(MatchEntry matchEntry, short ofVersion, MatchPath matchPath) {
161         ExtensionListBuilder extListBld = null;
162
163         /** TODO: EXTENSION PROPOSAL (match, OFJava to MD-SAL) */
164         MatchEntrySerializerKey<? extends OxmClassBase, ? extends MatchField> key = new MatchEntrySerializerKey<>(
165                 ofVersion, matchEntry.getOxmClass(), matchEntry.getOxmMatchField());
166         if (null != OFSessionUtil.getExtensionConvertorProvider()) {
167             ConvertorFromOFJava<MatchEntry, MatchPath> convertor = OFSessionUtil.getExtensionConvertorProvider().getConverter(key);
168             if (convertor != null) {
169                 ExtensionAugment<? extends Augmentation<Extension>> extensionMatch =
170                         convertor.convert(matchEntry, matchPath);
171                 ExtensionBuilder extBld = new ExtensionBuilder();
172                 extBld.addAugmentation(extensionMatch.getAugmentationClass(), extensionMatch.getAugmentationObject());
173
174                 extListBld = new ExtensionListBuilder();
175                 extListBld.setExtension(extBld.build());
176                 extListBld.setExtensionKey(extensionMatch.getKey());
177             }
178         }
179         return extListBld;
180     }
181
182 }