2 * Copyright (c) 2014 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.openflow.md.core.extension;
10 import java.util.ArrayList;
11 import java.util.Collection;
12 import java.util.HashMap;
13 import java.util.List;
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.augments.rev150225.oxm.container.match.entry.value.ExperimenterIdCase;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ExperimenterClass;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmClassBase;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlowBuilder;
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.GeneralAugMatchNotifUpdateFlowStatsBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchPacketInMessage;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchPacketInMessageBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchRpcOutputFlowStats;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchRpcOutputFlowStatsBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.Extension;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.ExtensionBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionListBuilder;
44 import org.opendaylight.yangtools.yang.binding.Augmentable;
45 import org.opendaylight.yangtools.yang.binding.Augmentation;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
49 public final class MatchExtensionHelper {
51 private static final Logger LOG = LoggerFactory.getLogger(MatchExtensionHelper.class);
53 private MatchExtensionHelper() {
54 throw new IllegalAccessError("singleton enforcement");
58 * Injects an extension.
60 * @param matchEntry match entry
61 * @param ofVersion openflow version
62 * @param matchPath match path
64 public static void injectExtension(
65 final short ofVersion,
66 final MatchEntry matchEntry,
67 final MatchBuilder matchBuilder,
68 final MatchPath matchPath) {
70 final ExtensionListBuilder extBuilder = processExtension(matchEntry, ofVersion, matchPath);
72 // TODO: remove the Optional.ofNullable() here, which will result more performant and easier to understand code
73 final GeneralAugMatchNodesNodeTableFlowBuilder builder = Optional
74 .ofNullable(matchBuilder.augmentation(GeneralAugMatchNodesNodeTableFlow.class))
75 .map(GeneralAugMatchNodesNodeTableFlowBuilder::new)
76 .orElse(new GeneralAugMatchNodesNodeTableFlowBuilder().setExtensionList(new HashMap<>()));
78 if (extBuilder != null) {
79 final ExtensionList ext = extBuilder.build();
80 builder.getExtensionList().put(ext.key(), ext);
82 LOG.warn("Convertor for {} for version {} with match path {} not found.",
83 matchEntry, ofVersion, matchPath.name());
86 matchBuilder.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, builder.build());
90 * Processes all extensions.
92 * @param matchEntries match entries
93 * @param ofVersion openflow version
94 * @param matchPath match path
95 * @param <E> extension point
96 * @return augmentation wrapper containing augmentation depending on matchPath
98 @SuppressWarnings("unchecked")
99 public static <E extends Augmentable<E>> AugmentTuple<E> processAllExtensions(
100 final Collection<MatchEntry> matchEntries, final OpenflowVersion ofVersion, final MatchPath matchPath) {
101 List<ExtensionList> extensionsList = new ArrayList<>();
103 if (matchEntries != null) {
104 for (MatchEntry matchEntry : matchEntries) {
105 ExtensionListBuilder extensionListBld = processExtension(matchEntry, ofVersion.getVersion(), matchPath);
106 if (extensionListBld == null) {
110 extensionsList.add(extensionListBld.build());
114 AugmentTuple<E> augmentTuple = null;
115 if (!extensionsList.isEmpty()) {
117 case FLOWS_STATISTICS_UPDATE_MATCH:
118 GeneralAugMatchNotifUpdateFlowStatsBuilder generalExtMatchAugBld1 =
119 new GeneralAugMatchNotifUpdateFlowStatsBuilder();
120 generalExtMatchAugBld1.setExtensionList(extensionsList);
121 augmentTuple = (AugmentTuple<E>)
123 GeneralAugMatchNotifUpdateFlowStats.class, generalExtMatchAugBld1.build());
125 case PACKET_RECEIVED_MATCH:
126 GeneralAugMatchNotifPacketInBuilder generalExtMatchAugBld2 =
127 new GeneralAugMatchNotifPacketInBuilder();
128 generalExtMatchAugBld2.setExtensionList(extensionsList);
129 augmentTuple = (AugmentTuple<E>)
130 new AugmentTuple<>(GeneralAugMatchNotifPacketIn.class, generalExtMatchAugBld2.build());
132 case PACKET_IN_MESSAGE_MATCH:
133 GeneralAugMatchPacketInMessageBuilder generalExtMatchAugBld5 =
134 new GeneralAugMatchPacketInMessageBuilder();
135 generalExtMatchAugBld5.setExtensionList(extensionsList);
136 augmentTuple = (AugmentTuple<E>)
137 new AugmentTuple<>(GeneralAugMatchPacketInMessage.class, generalExtMatchAugBld5.build());
139 case SWITCH_FLOW_REMOVED_MATCH:
140 GeneralAugMatchNotifSwitchFlowRemovedBuilder generalExtMatchAugBld3 =
141 new GeneralAugMatchNotifSwitchFlowRemovedBuilder();
142 generalExtMatchAugBld3.setExtensionList(extensionsList);
143 augmentTuple = (AugmentTuple<E>)
145 GeneralAugMatchNotifSwitchFlowRemoved.class, generalExtMatchAugBld3.build());
147 case FLOWS_STATISTICS_RPC_MATCH:
148 GeneralAugMatchRpcOutputFlowStatsBuilder generalExtMatchAugBld4 =
149 new GeneralAugMatchRpcOutputFlowStatsBuilder();
150 generalExtMatchAugBld4.setExtensionList(extensionsList);
151 augmentTuple = (AugmentTuple<E>)
153 GeneralAugMatchRpcOutputFlowStats.class, generalExtMatchAugBld4.build());
156 LOG.warn("matchPath not supported: {}", matchPath);
164 * Processes an extension.
166 * @param ofVersion openflow version
167 * @param matchPath match path
168 * @param matchEntry match entry
169 * @return an ExtensionListBuilder
171 private static ExtensionListBuilder processExtension(final MatchEntry matchEntry, final short ofVersion,
172 final MatchPath matchPath) {
173 ExtensionListBuilder extListBld = null;
175 // TODO: EXTENSION PROPOSAL (match, OFJava to MD-SAL)
176 MatchEntrySerializerKey<? extends OxmClassBase, ? extends MatchField> key = new MatchEntrySerializerKey<>(
177 ofVersion, matchEntry.getOxmClass(), matchEntry.getOxmMatchField());
179 // If entry is experimenter, set experimenter ID to key
180 if (matchEntry.getOxmClass().equals(ExperimenterClass.class)) {
181 ExperimenterIdCase experimenterIdCase = (ExperimenterIdCase) matchEntry.getMatchEntryValue();
182 key.setExperimenterId(experimenterIdCase.getExperimenter().getExperimenter().getValue());
185 if (null != OFSessionUtil.getExtensionConvertorProvider()) {
186 ConvertorFromOFJava<MatchEntry, MatchPath> convertor =
187 OFSessionUtil.getExtensionConvertorProvider().getConverter(key);
188 if (convertor != null) {
189 ExtensionAugment<? extends Augmentation<Extension>> extensionMatch =
190 convertor.convert(matchEntry, matchPath);
191 ExtensionBuilder extBld = new ExtensionBuilder();
192 extBld.addAugmentation(extensionMatch.getAugmentationClass(), extensionMatch.getAugmentationObject());
194 extListBld = new ExtensionListBuilder();
195 extListBld.setExtension(extBld.build());
196 extListBld.setExtensionKey(extensionMatch.getKey());