4938e41b89aaae7cb31c58e810bd4dbd381a47af
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / sal / convertor / ActionConvertor.java
1 /**
2  * Copyright (c) 2014 Ericsson India Global Services Pvt Ltd. 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  * Contributor: hema.gopalkrishnan@ericsson.com
9  */
10 package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor;
11
12 import com.google.common.collect.Ordering;
13 import org.opendaylight.openflowplugin.extension.api.ConverterExtensionKey;
14 import org.opendaylight.openflowplugin.extension.api.ConvertorActionToOFJava;
15 import org.opendaylight.openflowplugin.extension.api.ConvertorToOFJava;
16 import org.opendaylight.openflowplugin.extension.api.TypeVersionKey;
17 import org.opendaylight.openflowplugin.extension.api.path.ActionPath;
18 import org.opendaylight.openflowplugin.openflow.md.OFConstants;
19 import org.opendaylight.openflowplugin.openflow.md.core.extension.ActionExtensionHelper;
20 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.action.ActionSetNwDstReactor;
21 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.action.ActionSetNwSrcReactor;
22 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.OrderComparator;
23 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchConvertorImpl;
24 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchReactor;
25 import org.opendaylight.openflowplugin.openflow.md.core.session.OFSessionUtil;
26 import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
27 import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;
28 import org.opendaylight.openflowplugin.openflow.md.util.OpenflowVersion;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Dscp;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.CopyTtlInCase;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.CopyTtlInCaseBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.CopyTtlOutCase;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.CopyTtlOutCaseBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DecMplsTtlCase;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DecMplsTtlCaseBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DecNwTtlCase;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DecNwTtlCaseBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCase;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCaseBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopMplsActionCase;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopMplsActionCaseBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopPbbActionCase;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopPbbActionCaseBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCase;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCaseBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushMplsActionCase;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushMplsActionCaseBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushPbbActionCase;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushPbbActionCaseBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCaseBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlDstActionCase;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlSrcActionCase;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCaseBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetMplsTtlActionCase;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetMplsTtlActionCaseBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionCase;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwSrcActionCase;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwTosActionCase;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwTtlActionCase;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwTtlActionCaseBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetQueueActionCase;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetQueueActionCaseBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpDstActionCase;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpSrcActionCase;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCase;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanPcpActionCase;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.StripVlanActionCase;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.copy.ttl.in._case.CopyTtlInBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.copy.ttl.out._case.CopyTtlOutBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.mpls.ttl._case.DecMplsTtlBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtlBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.group.action._case.GroupAction;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.group.action._case.GroupActionBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputAction;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.mpls.action._case.PopMplsActionBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.pbb.action._case.PopPbbActionBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.mpls.action._case.PushMplsActionBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.pbb.action._case.PushPbbActionBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.vlan.action._case.PushVlanAction;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.vlan.action._case.PushVlanActionBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.dst.action._case.SetDlDstAction;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.src.action._case.SetDlSrcAction;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetField;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.mpls.ttl.action._case.SetMplsTtlAction;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.mpls.ttl.action._case.SetMplsTtlActionBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.tos.action._case.SetNwTosAction;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.ttl.action._case.SetNwTtlActionBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.queue.action._case.SetQueueAction;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.queue.action._case.SetQueueActionBuilder;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.tp.dst.action._case.SetTpDstAction;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.tp.src.action._case.SetTpSrcAction;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.vlan.id.action._case.SetVlanIdAction;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.vlan.pcp.action._case.SetVlanPcpAction;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.CommonPort;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.DlAddressAction;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.DlAddressActionBuilder;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthertypeAction;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthertypeActionBuilder;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.GroupIdAction;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.GroupIdActionBuilder;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaxLengthAction;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaxLengthActionBuilder;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MplsTtlAction;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MplsTtlActionBuilder;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NwTosAction;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NwTosActionBuilder;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NwTtlAction;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NwTtlActionBuilder;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmFieldsAction;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmFieldsActionBuilder;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortAction;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortActionBuilder;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortMatchEntry;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortMatchEntryBuilder;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.QueueIdAction;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.QueueIdActionBuilder;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanPcpAction;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanPcpActionBuilder;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanVidAction;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanVidActionBuilder;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanVidMatchEntry;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanVidMatchEntryBuilder;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Group;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopMpls;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopPbb;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopVlan;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushMpls;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushPbb;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushVlan;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetMplsTtl;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetNwTtl;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetQueue;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.grouping.Action;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.grouping.ActionBuilder;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.EtherType;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.EthDst;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.EthSrc;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OpenflowBasicClass;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.TcpDst;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.TcpSrc;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.VlanVid;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntries;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntriesBuilder;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.ExtensionKey;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralExtensionGrouping;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.Extension;
155 import org.slf4j.Logger;
156 import org.slf4j.LoggerFactory;
157
158 import java.math.BigInteger;
159 import java.util.ArrayList;
160 import java.util.List;
161
162 /**
163  * @author usha@ericsson Action List:This class takes data from SAL layer and
164  *         converts into OF Data
165  * @author avishnoi@in.ibm.com Added convertor for OF bucket actions to SAL
166  *         actions
167  */
168 public final class ActionConvertor {
169     private static final Logger logger = LoggerFactory.getLogger(ActionConvertor.class);
170
171     private ActionConvertor() {
172         // NOOP
173     }
174
175     /**
176      * Translates SAL actions into OF Library actions
177      *
178      * @param actions    SAL actions
179      * @param version    Openflow protocol version used
180      * @param datapathid
181      * @return OF Library actions
182      */
183     public static List<Action> getActions(
184             List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actions,
185             short version, BigInteger datapathid) {
186         List<Action> actionsList = new ArrayList<>();
187         Action ofAction;
188
189         actions = Ordering.from(OrderComparator.<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action>toInstance())
190             .sortedCopy(actions);
191
192         for (int actionItem = 0; actionItem < actions.size(); actionItem++) {
193             ofAction = null;
194             ActionBuilder actionBuilder = new ActionBuilder();
195
196             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action = actions.get(
197                     actionItem).getAction();
198
199             if (action instanceof OutputActionCase)
200                 ofAction = salToOFOutputAction(action, actionBuilder, version);
201             else if (action instanceof GroupActionCase)
202                 ofAction = SalToOFGroupAction(action, actionBuilder);
203             else if (action instanceof CopyTtlOutCase)
204                 ofAction = SalToOFCopyTTLIOut(actionBuilder);
205             else if (action instanceof CopyTtlInCase)
206                 ofAction = SalToOFCopyTTLIIn(actionBuilder);
207             else if (action instanceof SetMplsTtlActionCase)
208                 ofAction = SalToOFSetMplsTtl(action, actionBuilder);
209             else if (action instanceof DecMplsTtlCase)
210                 ofAction = SalToOFDecMplsTtl(actionBuilder);
211             else if (action instanceof PushVlanActionCase)
212                 ofAction = SalToOFPushVlanAction(action, actionBuilder, version);
213             else if (action instanceof PopVlanActionCase)
214                 ofAction = (version == OFConstants.OFP_VERSION_1_0) ?
215                     SalToOFStripVlan(actionBuilder, version)
216                         : SalToOFPopVlan(actionBuilder);
217             else if (action instanceof PushMplsActionCase)
218                 ofAction = SalToOFPushMplsAction(action, actionBuilder);
219             else if (action instanceof PopMplsActionCase)
220                 ofAction = SalToOFPopMpls(action, actionBuilder);
221             else if (action instanceof SetQueueActionCase)
222                 ofAction = SalToOFSetQueue(action, actionBuilder);
223             else if (action instanceof SetNwTtlActionCase)
224                 ofAction = SalToOFSetNwTtl(action, actionBuilder);
225             else if (action instanceof DecNwTtlCase)
226                 ofAction = SalToOFDecNwTtl(actionBuilder);
227             else if (action instanceof SetFieldCase)
228                 ofAction = SalToOFSetField(action, actionBuilder, version, datapathid);
229             else if (action instanceof PushPbbActionCase)
230                 ofAction = SalToOFPushPbbAction(action, actionBuilder);
231             else if (action instanceof PopPbbActionCase)
232                 ofAction = SalToOFPopPBB(actionBuilder);
233
234                 // 1.0 Actions
235             else if (action instanceof SetVlanIdActionCase) {
236                 /*if (version == OFConstants.OFP_VERSION_1_0) {
237
238                 } else {
239                     List<Action> setVlanIdActionsList = convertToOF13(action, actionBuilder);
240                     actionsList.addAll(setVlanIdActionsList);
241                 }*/
242                 ofAction = SalToOFSetVlanId(action, actionBuilder, version);
243             }
244             else if (action instanceof SetVlanPcpActionCase)
245                 ofAction = SalToOFSetVlanpcp(action, actionBuilder, version);
246             else if (action instanceof StripVlanActionCase)
247                 ofAction = SalToOFStripVlan(actionBuilder, version);
248             else if (action instanceof SetDlSrcActionCase)
249                 ofAction = SalToOFSetDlSrc(action, actionBuilder, version);
250             else if (action instanceof SetDlDstActionCase)
251                 ofAction = SalToOFSetDlDst(action, actionBuilder, version);
252             else if (action instanceof SetNwSrcActionCase)
253                 ofAction = SalToOFSetNwSrc(action, actionBuilder, version);
254             else if (action instanceof SetNwDstActionCase)
255                 ofAction = SalToOFSetNwDst(action, actionBuilder, version);
256             else if (action instanceof SetTpSrcActionCase)
257                 ofAction = SalToOFSetTpSrc(action, actionBuilder, version);
258             else if (action instanceof SetTpDstActionCase)
259                 ofAction = SalToOFSetTpDst(action, actionBuilder, version);
260             else if (action instanceof SetNwTosActionCase)
261                 ofAction = SalToOFSetNwTos(action, actionBuilder, version);
262             else if (action instanceof GeneralExtensionGrouping) {
263                 
264                 /**
265                  * TODO: EXTENSION PROPOSAL (action, MD-SAL to OFJava)
266                  * - we might need sessionContext as converter input
267                  * 
268                  */
269                 
270                 GeneralExtensionGrouping extensionCaseGrouping = (GeneralExtensionGrouping) action;
271                 Extension extAction = extensionCaseGrouping.getExtension();
272                 ConverterExtensionKey<? extends ExtensionKey> key = new ConverterExtensionKey<>(extensionCaseGrouping.getExtensionKey(), version);
273                 ConvertorToOFJava<Action> convertor = 
274                         OFSessionUtil.getExtensionConvertorProvider().getConverter(key);
275                 if (convertor != null) {
276                     ofAction = convertor.convert(extAction);
277                 }
278             } else {
279                 // try vendor codecs
280                 TypeVersionKey<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action> key =
281                         new TypeVersionKey<>(
282                                 (Class<? extends org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action>) action.getImplementedInterface(),
283                                 version);
284                 ConvertorActionToOFJava<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action, Action> convertor = 
285                         OFSessionUtil.getExtensionConvertorProvider().getConverter(key);
286                 if (convertor != null) {
287                     ofAction = convertor.convert(action);
288                 }
289             }
290             
291             if (ofAction != null) {
292                 actionsList.add(ofAction);
293             }
294         }
295         return actionsList;
296     }
297
298     private static Action SalToOFSetField(
299             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action,
300             ActionBuilder actionBuilder, short version, BigInteger datapathid) {
301
302         SetFieldCase setFieldCase = (SetFieldCase) action;
303         org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match match =
304             setFieldCase.getSetField();
305
306         if (version == OFConstants.OFP_VERSION_1_0) {
307             // pushvlan +setField can be called to configure 1.0 switches via MDSAL app
308             if (match.getVlanMatch() != null) {
309                 VlanVidActionBuilder vlanidActionBuilder = new VlanVidActionBuilder();
310                 vlanidActionBuilder.setVlanVid(match.getVlanMatch().getVlanId().getVlanId().getValue());
311                 actionBuilder.setType(
312                     org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetVlanVid.class);
313                 actionBuilder.addAugmentation(VlanVidAction.class, vlanidActionBuilder.build());
314                 return actionBuilder.build();
315             } else {
316                 return emtpyAction(actionBuilder);
317             }
318
319         } else {
320             OxmFieldsActionBuilder oxmFieldsActionBuilder = new OxmFieldsActionBuilder();
321             MatchReactor.getInstance().convert(match, version, oxmFieldsActionBuilder, datapathid);
322
323             actionBuilder.setType(
324                 org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetField.class);
325
326             actionBuilder.addAugmentation(OxmFieldsAction.class, oxmFieldsActionBuilder.build());
327             return actionBuilder.build();
328         }
329
330     }
331
332     private static Action SalToOFDecNwTtl(ActionBuilder actionBuilder) {
333         actionBuilder
334                 .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.DecNwTtl.class);
335         return emtpyAction(actionBuilder);
336     }
337
338     private static Action SalToOFPushMplsAction(
339             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action,
340             ActionBuilder actionBuilder) {
341         PushMplsActionCase pushMplsActionCase = (PushMplsActionCase) action;
342         actionBuilder.setType(PushMpls.class);
343
344         return SalToOFPushAction(pushMplsActionCase.getPushMplsAction().getEthernetType(), actionBuilder);
345     }
346
347     private static Action SalToOFPushPbbAction(
348             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action,
349             ActionBuilder actionBuilder) {
350         PushPbbActionCase pushPbbActionCase = (PushPbbActionCase) action;
351         actionBuilder.setType(PushPbb.class);
352
353         return SalToOFPushAction(pushPbbActionCase.getPushPbbAction().getEthernetType(), actionBuilder);
354     }
355
356     private static Action SalToOFPushVlanAction(
357             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action,
358             ActionBuilder actionBuilder, short version) {
359         if (version == OFConstants.OFP_VERSION_1_0) {
360             // if client configure openflow 1.0 switch as a openflow 1.3 switch using openflow 1.3 instructions
361             // then we can ignore PUSH_VLAN as set-vlan-id will push a vlan header if not present
362             return emtpyAction(actionBuilder);
363         }
364
365         PushVlanActionCase pushVlanActionCase = (PushVlanActionCase) action;
366         PushVlanAction pushVlanAction = pushVlanActionCase.getPushVlanAction();
367         actionBuilder.setType(PushVlan.class);
368
369         return SalToOFPushAction(pushVlanAction.getEthernetType(), actionBuilder);
370     }
371
372     private static Action SalToOFSetNwTtl(
373             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action,
374             ActionBuilder actionBuilder) {
375         SetNwTtlActionCase nwTtlActionCase = (SetNwTtlActionCase) action;
376         NwTtlActionBuilder nwTtlActionBuilder = new NwTtlActionBuilder();
377         nwTtlActionBuilder.setNwTtl(nwTtlActionCase.getSetNwTtlAction().getNwTtl());
378         actionBuilder.setType(SetNwTtl.class);
379         actionBuilder.addAugmentation(NwTtlAction.class, nwTtlActionBuilder.build());
380         return actionBuilder.build();
381     }
382
383     private static Action SalToOFSetQueue(
384             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action,
385             ActionBuilder actionBuilder) {
386         SetQueueActionCase setQueueActionCase = (SetQueueActionCase) action;
387         SetQueueAction setQueueAction = setQueueActionCase.getSetQueueAction();
388
389         QueueIdActionBuilder queueIdActionBuilder = new QueueIdActionBuilder();
390         queueIdActionBuilder.setQueueId(setQueueAction.getQueueId());
391         actionBuilder.setType(SetQueue.class);
392         actionBuilder.addAugmentation(QueueIdAction.class, queueIdActionBuilder.build());
393
394         return actionBuilder.build();
395     }
396
397     private static Action SalToOFPopMpls(
398             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action,
399             ActionBuilder actionBuilder) {
400         PopMplsActionCase popMplsActionCase = (PopMplsActionCase) action;
401         actionBuilder.setType(PopMpls.class);
402
403         return SalToOFPushAction(popMplsActionCase.getPopMplsAction().getEthernetType(), actionBuilder);
404     }
405
406     private static Action SalToOFPopVlan(ActionBuilder actionBuilder) {
407         actionBuilder.setType(PopVlan.class);
408         return emtpyAction(actionBuilder);
409     }
410
411     private static Action SalToOFPopPBB(ActionBuilder actionBuilder) {
412         actionBuilder.setType(PopPbb.class);
413         return emtpyAction(actionBuilder);
414     }
415
416     // set-vlan-id (1.0 feature) can be called on  1.3 switches as well using ADSAL apis
417     private static Action SalToOFSetVlanId(
418             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action,
419             ActionBuilder actionBuilder, short version) {
420
421         SetVlanIdActionCase setvlanidcase = (SetVlanIdActionCase) action;
422         SetVlanIdAction setvlanidaction = setvlanidcase.getSetVlanIdAction();
423
424         if (version == OFConstants.OFP_VERSION_1_0) {
425
426             VlanVidActionBuilder vlanidActionBuilder = new VlanVidActionBuilder();
427             vlanidActionBuilder.setVlanVid(setvlanidaction.getVlanId().getValue());
428             actionBuilder
429                     .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetVlanVid.class);
430             actionBuilder.addAugmentation(VlanVidAction.class, vlanidActionBuilder.build());
431             return actionBuilder.build();
432
433         } else if (version >= OFConstants.OFP_VERSION_1_3) {
434             OxmFieldsActionBuilder oxmFieldsActionBuilder = new OxmFieldsActionBuilder();
435             actionBuilder
436                     .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetField.class);
437             List<MatchEntries> matchEntriesList = new ArrayList<>();
438             MatchEntriesBuilder matchEntriesBuilder = new MatchEntriesBuilder();
439             matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
440             matchEntriesBuilder.setOxmMatchField(VlanVid.class);
441             VlanVidMatchEntryBuilder vlanVidBuilder = new VlanVidMatchEntryBuilder();
442             vlanVidBuilder.setCfiBit(true);
443             vlanVidBuilder.setVlanVid(setvlanidaction.getVlanId().getValue());
444             matchEntriesBuilder.addAugmentation(VlanVidMatchEntry.class, vlanVidBuilder.build());
445             matchEntriesBuilder.setHasMask(false);
446             matchEntriesList.add(matchEntriesBuilder.build());
447             oxmFieldsActionBuilder.setMatchEntries(matchEntriesList);
448             actionBuilder.addAugmentation(OxmFieldsAction.class, oxmFieldsActionBuilder.build());
449             return actionBuilder.build();
450         } else {
451             logger.error("Unknown Action Type for the Version", version);
452             return null;
453         }
454     }
455
456     private static Action SalToOFSetVlanpcp(
457             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action,
458             ActionBuilder actionBuilder, short version) {
459
460         SetVlanPcpActionCase setvlanpcpcase = (SetVlanPcpActionCase) action;
461         SetVlanPcpAction setvlanpcpaction = setvlanpcpcase.getSetVlanPcpAction();
462
463         if (version == OFConstants.OFP_VERSION_1_0) {
464             VlanPcpActionBuilder vlanpcpActionBuilder = new VlanPcpActionBuilder();
465             vlanpcpActionBuilder.setVlanPcp(setvlanpcpaction.getVlanPcp().getValue());
466             actionBuilder
467                     .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetVlanPcp.class);
468             actionBuilder.addAugmentation(VlanPcpAction.class, vlanpcpActionBuilder.build());
469             return actionBuilder.build();
470         } else if (version >= OFConstants.OFP_VERSION_1_3) {
471             OxmFieldsActionBuilder oxmFieldsActionBuilder = new OxmFieldsActionBuilder();
472             actionBuilder
473                     .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetField.class);
474             List<MatchEntries> matchEntriesList = new ArrayList<>();
475             matchEntriesList.add(MatchConvertorImpl.toOfVlanPcp(setvlanpcpaction.getVlanPcp()));
476             oxmFieldsActionBuilder.setMatchEntries(matchEntriesList);
477             actionBuilder.addAugmentation(OxmFieldsAction.class, oxmFieldsActionBuilder.build());
478             return actionBuilder.build();
479         } else {
480             logger.error("Unknown Action Type for the Version", version);
481             return null;
482         }
483     }
484
485     private static Action SalToOFStripVlan(ActionBuilder actionBuilder, short version) {
486         if (version == OFConstants.OFP_VERSION_1_0) {
487             actionBuilder
488                     .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.StripVlan.class);
489
490             return emtpyAction(actionBuilder);
491         } else if (version >= OFConstants.OFP_VERSION_1_3) {
492             OxmFieldsActionBuilder oxmFieldsActionBuilder = new OxmFieldsActionBuilder();
493             actionBuilder
494                     .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetField.class);
495             List<MatchEntries> matchEntriesList = new ArrayList<>();
496             MatchEntriesBuilder matchEntriesBuilder = new MatchEntriesBuilder();
497             matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
498             matchEntriesBuilder.setOxmMatchField(VlanVid.class);
499             VlanVidMatchEntryBuilder vlanVidBuilder = new VlanVidMatchEntryBuilder();
500             vlanVidBuilder.setCfiBit(true);
501             vlanVidBuilder.setVlanVid(0x0000);
502             matchEntriesBuilder.addAugmentation(VlanVidMatchEntry.class, vlanVidBuilder.build());
503             matchEntriesBuilder.setHasMask(false);
504             matchEntriesList.add(matchEntriesBuilder.build());
505             oxmFieldsActionBuilder.setMatchEntries(matchEntriesList);
506             actionBuilder.addAugmentation(OxmFieldsAction.class, oxmFieldsActionBuilder.build());
507             return actionBuilder.build();
508         } else {
509             logger.error("Unknown Action Type for the Version", version);
510             return null;
511         }
512     }
513
514     private static Action SalToOFSetDlSrc(
515             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action,
516             ActionBuilder actionBuilder, short version) {
517
518         SetDlSrcActionCase setdlsrccase = (SetDlSrcActionCase) action;
519         SetDlSrcAction setdlsrcaction = setdlsrccase.getSetDlSrcAction();
520
521         if (version == OFConstants.OFP_VERSION_1_0) {
522             DlAddressActionBuilder dladdressactionbuilder = new DlAddressActionBuilder();
523             dladdressactionbuilder.setDlAddress(setdlsrcaction.getAddress());
524             actionBuilder
525                     .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetDlSrc.class);
526             actionBuilder.addAugmentation(DlAddressAction.class, dladdressactionbuilder.build());
527             return actionBuilder.build();
528         } else if (version >= OFConstants.OFP_VERSION_1_3) {
529             OxmFieldsActionBuilder oxmFieldsActionBuilder = new OxmFieldsActionBuilder();
530             actionBuilder
531                     .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetField.class);
532             List<MatchEntries> matchEntriesList = new ArrayList<>();
533             matchEntriesList.add(MatchConvertorImpl.toOfMacAddress(EthSrc.class, setdlsrcaction.getAddress(), null));
534             oxmFieldsActionBuilder.setMatchEntries(matchEntriesList);
535             actionBuilder.addAugmentation(OxmFieldsAction.class, oxmFieldsActionBuilder.build());
536             return actionBuilder.build();
537         } else {
538             logger.error("Unknown Action Type for the Version", version);
539             return null;
540         }
541     }
542
543     private static Action SalToOFSetDlDst(
544             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action,
545             ActionBuilder actionBuilder, short version) {
546
547         SetDlDstActionCase setdldstcase = (SetDlDstActionCase) action;
548         SetDlDstAction setdldstaction = setdldstcase.getSetDlDstAction();
549
550         if (version == OFConstants.OFP_VERSION_1_0) {
551             DlAddressActionBuilder dladdressactionbuilder = new DlAddressActionBuilder();
552             dladdressactionbuilder.setDlAddress(setdldstaction.getAddress());
553             actionBuilder
554                     .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetDlDst.class);
555             actionBuilder.addAugmentation(DlAddressAction.class, dladdressactionbuilder.build());
556             return actionBuilder.build();
557         } else if (version >= OFConstants.OFP_VERSION_1_3) {
558             OxmFieldsActionBuilder oxmFieldsActionBuilder = new OxmFieldsActionBuilder();
559             actionBuilder
560                     .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetField.class);
561             List<MatchEntries> matchEntriesList = new ArrayList<>();
562             matchEntriesList.add(MatchConvertorImpl.toOfMacAddress(EthDst.class, setdldstaction.getAddress(), null));
563             oxmFieldsActionBuilder.setMatchEntries(matchEntriesList);
564             actionBuilder.addAugmentation(OxmFieldsAction.class, oxmFieldsActionBuilder.build());
565             return actionBuilder.build();
566         } else {
567             logger.error("Unknown Action Type for the Version", version);
568             return null;
569         }
570     }
571
572     protected static Action SalToOFSetNwSrc(
573             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action,
574             ActionBuilder actionBuilder, short version) {
575
576         try {
577             ActionSetNwSrcReactor.getInstance().convert((SetNwSrcActionCase) action, version, actionBuilder, null);
578         } catch (Exception e) {
579             logger.error(e.getMessage(), e);
580             return null;
581         }
582
583         return actionBuilder.build();
584     }
585
586     protected static Action SalToOFSetNwDst(
587             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action,
588             ActionBuilder actionBuilder, short version) {
589
590         try {
591             ActionSetNwDstReactor.getInstance().convert((SetNwDstActionCase) action, version, actionBuilder, null);
592         } catch (Exception e) {
593             logger.error(e.getMessage(), e);
594             return null;
595         }
596
597         return actionBuilder.build();
598     }
599
600     private static Action SalToOFSetNwTos(
601             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action,
602             ActionBuilder actionBuilder, short version) {
603
604         SetNwTosActionCase setnwtoscase = (SetNwTosActionCase) action;
605         SetNwTosAction setnwtosaction = setnwtoscase.getSetNwTosAction();
606
607         if (version == OFConstants.OFP_VERSION_1_0) {
608             NwTosActionBuilder tosBuilder = new NwTosActionBuilder();
609             tosBuilder.setNwTos(setnwtosaction.getTos().shortValue());
610             actionBuilder.addAugmentation(NwTosAction.class, tosBuilder.build());
611             actionBuilder
612                     .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetNwTos.class);
613
614             return actionBuilder.build();
615         } else if (version >= OFConstants.OFP_VERSION_1_3) {
616             OxmFieldsActionBuilder oxmFieldsActionBuilder = new OxmFieldsActionBuilder();
617             actionBuilder
618                     .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetField.class);
619             List<MatchEntries> matchEntriesList = new ArrayList<>();
620             matchEntriesList.add(MatchConvertorImpl.toOfIpDscp(new Dscp(setnwtosaction.getTos().shortValue())));
621             oxmFieldsActionBuilder.setMatchEntries(matchEntriesList);
622             actionBuilder.addAugmentation(OxmFieldsAction.class, oxmFieldsActionBuilder.build());
623             return actionBuilder.build();
624         } else {
625             logger.error("Unknown Action Type for the Version", version);
626             return null;
627         }
628
629     }
630
631     private static Action SalToOFSetTpSrc(
632             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action,
633             ActionBuilder actionBuilder, short version) {
634
635         if (version == OFConstants.OFP_VERSION_1_0) {
636             SetTpSrcActionCase settpsrccase = (SetTpSrcActionCase) action;
637             SetTpSrcAction settpsrcaction = settpsrccase.getSetTpSrcAction();
638
639             PortActionBuilder settpsrc = new PortActionBuilder();
640             PortNumber port = new PortNumber(settpsrcaction.getPort().getValue().longValue());
641             settpsrc.setPort(port);
642
643             actionBuilder
644                     .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetTpSrc.class);
645             actionBuilder.addAugmentation(PortAction.class, settpsrc.build());
646             return actionBuilder.build();
647         } else if (version == OFConstants.OFP_VERSION_1_3) {
648             SetTpSrcActionCase settpsrccase = (SetTpSrcActionCase) action;
649             SetTpSrcAction settpsrcaction = settpsrccase.getSetTpSrcAction();
650             
651             MatchEntriesBuilder matchEntriesBuilder = new MatchEntriesBuilder();
652             matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
653             matchEntriesBuilder.setHasMask(false);
654             matchEntriesBuilder.setOxmMatchField(TcpSrc.class);
655             PortMatchEntryBuilder portMatchEntryBuilder = new PortMatchEntryBuilder();
656             portMatchEntryBuilder.setPort(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber(settpsrcaction.getPort().getValue().intValue()));
657             matchEntriesBuilder.addAugmentation(PortMatchEntry.class, portMatchEntryBuilder.build());
658             
659             actionBuilder
660             .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetField.class);
661             
662             OxmFieldsActionBuilder oxmFieldsActionBuilder = new OxmFieldsActionBuilder();
663             List<MatchEntries> matchEntries = new ArrayList<MatchEntries>();
664             matchEntries.add(matchEntriesBuilder.build());
665             oxmFieldsActionBuilder.setMatchEntries(matchEntries);
666
667             actionBuilder.addAugmentation(OxmFieldsAction.class, oxmFieldsActionBuilder.build());
668             return actionBuilder.build();
669         }
670         logger.error("Unknown Action Type for the Version", version);
671         return null;
672     }
673
674     private static Action SalToOFSetTpDst(
675             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action,
676             ActionBuilder actionBuilder, short version) {
677
678         if (version == OFConstants.OFP_VERSION_1_0) {
679             SetTpDstActionCase settpdstcase = (SetTpDstActionCase) action;
680             SetTpDstAction settpdstaction = settpdstcase.getSetTpDstAction();
681             PortActionBuilder settpdst = new PortActionBuilder();
682             PortNumber port = new PortNumber(settpdstaction.getPort().getValue().longValue());
683             settpdst.setPort(port);
684
685             actionBuilder
686                     .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetTpDst.class);
687             actionBuilder.addAugmentation(PortAction.class, settpdst.build());
688             return actionBuilder.build();
689         } else if (version == OFConstants.OFP_VERSION_1_3) {
690             SetTpDstActionCase settpdstcase = (SetTpDstActionCase) action;
691             SetTpDstAction settpdstaction = settpdstcase.getSetTpDstAction();
692             
693             MatchEntriesBuilder matchEntriesBuilder = new MatchEntriesBuilder();
694             matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
695             matchEntriesBuilder.setHasMask(false);
696             matchEntriesBuilder.setOxmMatchField(TcpDst.class);
697             PortMatchEntryBuilder portMatchEntryBuilder = new PortMatchEntryBuilder();
698             portMatchEntryBuilder.setPort(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber(settpdstaction.getPort().getValue().intValue()));
699             matchEntriesBuilder.addAugmentation(PortMatchEntry.class, portMatchEntryBuilder.build());
700             
701             actionBuilder
702             .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetField.class);
703             
704             OxmFieldsActionBuilder oxmFieldsActionBuilder = new OxmFieldsActionBuilder();
705             List<MatchEntries> matchEntries = new ArrayList<MatchEntries>();
706             matchEntries.add(matchEntriesBuilder.build());
707             oxmFieldsActionBuilder.setMatchEntries(matchEntries);
708
709             actionBuilder.addAugmentation(OxmFieldsAction.class, oxmFieldsActionBuilder.build());
710             return actionBuilder.build();
711         }
712         logger.error("Unknown Action Type for the Version", version);
713         return null;
714     }
715
716     private static Action SalToOFGroupAction(
717             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action,
718             ActionBuilder actionBuilder) {
719
720         GroupActionCase groupActionCase = (GroupActionCase) action;
721         GroupAction groupAction = groupActionCase.getGroupAction();
722
723         GroupIdActionBuilder groupIdBuilder = new GroupIdActionBuilder();
724         groupIdBuilder.setGroupId(groupAction.getGroupId());
725         actionBuilder.setType(Group.class);
726         actionBuilder.addAugmentation(GroupIdAction.class, groupIdBuilder.build());
727         return actionBuilder.build();
728     }
729
730     private static Action SalToOFPushAction(Integer ethernetType, ActionBuilder actionBuilder) {
731         EthertypeActionBuilder ethertypeActionBuilder = new EthertypeActionBuilder();
732         if (ethernetType != null) {
733             ethertypeActionBuilder.setEthertype(new EtherType(ethernetType));
734         }
735
736         /* OF */
737         actionBuilder.addAugmentation(EthertypeAction.class, ethertypeActionBuilder.build());
738         return actionBuilder.build();
739     }
740
741     private static Action SalToOFDecMplsTtl(ActionBuilder actionBuilder) {
742         actionBuilder
743                 .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.DecMplsTtl.class);
744         return emtpyAction(actionBuilder);
745     }
746
747     private static Action SalToOFSetMplsTtl(
748             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action,
749             ActionBuilder actionBuilder) {
750         SetMplsTtlActionCase mplsTtlActionCase = (SetMplsTtlActionCase) action;
751         SetMplsTtlAction mplsTtlAction = mplsTtlActionCase.getSetMplsTtlAction();
752
753         MplsTtlActionBuilder mplsTtlActionBuilder = new MplsTtlActionBuilder();
754         mplsTtlActionBuilder.setMplsTtl(mplsTtlAction.getMplsTtl()/* SAL */);
755         /* OF */
756         actionBuilder.setType(SetMplsTtl.class);
757         actionBuilder.addAugmentation(MplsTtlAction.class, mplsTtlActionBuilder.build());
758         return actionBuilder.build();
759     }
760
761     private static Action SalToOFCopyTTLIIn(ActionBuilder actionBuilder) {
762         actionBuilder
763                 .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.CopyTtlIn.class);
764         return emtpyAction(actionBuilder);
765     }
766
767     private static Action SalToOFCopyTTLIOut(ActionBuilder actionBuilder) {
768         actionBuilder
769                 .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.CopyTtlOut.class);
770         return emtpyAction(actionBuilder);
771
772     }
773
774     private static Action emtpyAction(ActionBuilder actionBuilder) {
775         return actionBuilder.build();
776     }
777
778     private static Action salToOFOutputAction(
779             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action,
780             ActionBuilder actionBuilder, short version) {
781
782         OutputActionCase outputActionCase = ((OutputActionCase) action);
783         OutputAction outputAction = outputActionCase.getOutputAction();
784         PortActionBuilder portAction = new PortActionBuilder();
785         MaxLengthActionBuilder maxLenActionBuilder = new MaxLengthActionBuilder();
786         if (outputAction.getMaxLength() != null) {
787             maxLenActionBuilder.setMaxLength(outputAction.getMaxLength());
788         } else {
789             maxLenActionBuilder.setMaxLength(0);
790         }
791         actionBuilder.addAugmentation(MaxLengthAction.class, maxLenActionBuilder.build());
792
793         Uri uri = outputAction.getOutputNodeConnector();
794
795         OpenflowVersion ofVersion = OpenflowVersion.get(version);
796         Long portNumber = InventoryDataServiceUtil.portNumberfromNodeConnectorId(ofVersion, uri.getValue());
797         if (OpenflowPortsUtil.checkPortValidity(ofVersion, portNumber)) {
798             portAction.setPort(new PortNumber(portNumber));
799         } else {
800             logger.error("Invalid Port specified " + portNumber + " for Output Action for OF version:" + ofVersion);
801         }
802
803         actionBuilder.setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Output.class);
804         actionBuilder.addAugmentation(PortAction.class, portAction.build());
805         return actionBuilder.build();
806
807     }
808
809     /**
810      * Method to convert OF actions associated with bucket to SAL Actions.
811      *
812      * @param actionList
813      * @param ofVersion  current ofp version
814      * @param actionPath TODO
815      * @return List of converted SAL Actions.
816      */
817     public static List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action> toMDSalActions(
818             List<Action> actionList, OpenflowVersion ofVersion, ActionPath actionPath) {
819
820         List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action> bucketActions = new ArrayList<>();
821         for (Action action : actionList) {
822             if (action.getType().equals(
823                     org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Output.class)) {
824                 bucketActions.add(ofToSALOutputAction(ofVersion, action));
825
826             } else if (action.getType().equals(
827                     org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Group.class)) {
828                 bucketActions.add(ofToSALGroupAction(action));
829
830             } else if (action.getType().equals(
831                     org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.CopyTtlOut.class)) {
832                 CopyTtlOutBuilder copyTtlOutaction = new CopyTtlOutBuilder();
833                 bucketActions.add(new CopyTtlOutCaseBuilder().setCopyTtlOut(copyTtlOutaction.build()).build());
834
835             } else if (action.getType().equals(
836                     org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.CopyTtlIn.class)) {
837                 CopyTtlInBuilder copyTtlInaction = new CopyTtlInBuilder();
838                 bucketActions.add(new CopyTtlInCaseBuilder().setCopyTtlIn(copyTtlInaction.build()).build());
839
840             } else if (action.getType().equals(
841                     org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetMplsTtl.class)) {
842                 bucketActions.add(ofToSALSetMplsTtl(action));
843
844             } else if (action.getType().equals(
845                     org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.DecMplsTtl.class)) {
846                 DecMplsTtlBuilder decMplsTtl = new DecMplsTtlBuilder();
847                 bucketActions.add(new DecMplsTtlCaseBuilder().setDecMplsTtl(decMplsTtl.build()).build());
848
849             } else if (action.getType().equals(
850                     org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushVlan.class)) {
851                 bucketActions.add(ofToSALPushVlanAction(action));
852
853             } else if (action.getType().equals(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopVlan.class)
854                     || action.getType().equals(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.StripVlan.class)) {
855                 // OF1.0 nodes will emit StripVlan and OF1.3+ will emit StripVlan/PopVlan, convert both to PopVlan for SAL
856                 PopVlanActionBuilder popVlan = new PopVlanActionBuilder();
857                 bucketActions.add(new PopVlanActionCaseBuilder().setPopVlanAction(popVlan.build()).build());
858
859             } else if (action.getType().equals(
860                     org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushMpls.class)) {
861                 bucketActions.add(ofToSALPushMplsAction(action));
862
863             } else if (action.getType().equals(
864                     org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopMpls.class)) {
865                 bucketActions.add(ofToSALPopMplsAction(action));
866
867             } else if (action.getType().equals(
868                     org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetQueue.class)) {
869                 bucketActions.add(ofToSALSetQueue(action));
870
871             } else if (action.getType().equals(
872                     org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetNwTtl.class)) {
873                 bucketActions.add(ofToSALSetNwTtl(action));
874
875             } else if (action.getType().equals(
876                     org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.DecNwTtl.class)) {
877                 DecNwTtlBuilder decNwTtl = new DecNwTtlBuilder();
878                 bucketActions.add(new DecNwTtlCaseBuilder().setDecNwTtl(decNwTtl.build()).build());
879
880             } else if (action.getType().equals(
881                     org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.SetField.class)) {
882                 bucketActions.add(new SetFieldCaseBuilder().setSetField(MatchConvertorImpl.fromOFSetFieldToSALSetFieldAction(action, ofVersion))
883                         .build());
884             } else if (action.getType().equals(
885                     org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PushPbb.class)) {
886                 bucketActions.add(ofToSALPushPbbAction(action));
887
888             } else if (action.getType().equals(
889                     org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.PopPbb.class)) {
890                 PopPbbActionBuilder popPbb = new PopPbbActionBuilder();
891                 bucketActions.add(new PopPbbActionCaseBuilder().setPopPbbAction(popPbb.build()).build());
892
893             } else if (action.getType().equals(
894                     org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Experimenter.class)) {
895                 /**
896                  * TODO: EXTENSION PROPOSAL (action, OFJava to MD-SAL)
897                  * - we might also need a way on how to identify exact type of augmentation to be 
898                  *   used as match can be bound to multiple models
899                  */
900                 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action processedAction = 
901                         ActionExtensionHelper.processAlienAction(action, ofVersion, actionPath);
902                 if (processedAction != null) {
903                     bucketActions.add(processedAction);
904                 }
905             }
906         }
907         return bucketActions;
908     }
909
910     /**
911      * Method converts OF Output action object to SAL Output action object.
912      *
913      * @param ofVersion
914      * @param ofVersion
915      * @param action    org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.
916      *                  action.rev130731.actions.actions.list.Action
917      * @return OutputAction
918      */
919     public static OutputActionCase ofToSALOutputAction(OpenflowVersion ofVersion, Action action) {
920         OutputActionBuilder outputAction = new OutputActionBuilder();
921         PortAction port = action.getAugmentation(PortAction.class);
922         if (port != null) {
923             CommonPort.PortNumber protocolAgnosticPort = OpenflowPortsUtil.getProtocolAgnosticPort(
924                     ofVersion, port.getPort().getValue());
925             String portNumberAsString = OpenflowPortsUtil.portNumberToString(protocolAgnosticPort);
926             outputAction.setOutputNodeConnector(new Uri(portNumberAsString));
927         } else {
928             logger.error("Provided action is not OF Output action, no associated port found!");
929         }
930
931         MaxLengthAction length = action.getAugmentation(MaxLengthAction.class);
932         if (length != null) {
933             outputAction.setMaxLength(length.getMaxLength());
934         } else {
935             logger.error("Provided action is not OF Output action, no associated length found!");
936         }
937
938         return new OutputActionCaseBuilder().setOutputAction(outputAction.build()).build();
939     }
940
941     /**
942      * Method converts OF GroupAction object to SAL GroupAction object
943      *
944      * @param action
945      * @return GroupAction
946      */
947     public static GroupActionCase ofToSALGroupAction(Action action) {
948
949         GroupActionBuilder groupAction = new GroupActionBuilder();
950
951         GroupIdAction groupId = action.getAugmentation(GroupIdAction.class);
952         groupAction.setGroupId(groupId.getGroupId());
953
954         return new GroupActionCaseBuilder().setGroupAction(groupAction.build()).build();
955     }
956
957     /**
958      * Method converts OF SetMplsTTL action object to SAL SetMplsTTL action
959      * object.
960      *
961      * @param action
962      * @return
963      */
964     public static SetMplsTtlActionCase ofToSALSetMplsTtl(Action action) {
965
966         SetMplsTtlActionBuilder mplsTtlAction = new SetMplsTtlActionBuilder();
967         MplsTtlAction mplsTtl = action.getAugmentation(MplsTtlAction.class);
968         mplsTtlAction.setMplsTtl(mplsTtl.getMplsTtl());
969         return new SetMplsTtlActionCaseBuilder().setSetMplsTtlAction(mplsTtlAction.build()).build();
970     }
971
972     /**
973      * Method converts OF Pushvlan action to SAL PushVlan action.
974      *
975      * @param action
976      * @return PushVlanAction
977      */
978     public static PushVlanActionCase ofToSALPushVlanAction(Action action) {
979
980         PushVlanActionBuilder pushVlanAction = new PushVlanActionBuilder();
981
982         EthertypeAction etherType = action.getAugmentation(EthertypeAction.class);
983         pushVlanAction.setEthernetType(etherType.getEthertype().getValue());
984
985         return new PushVlanActionCaseBuilder().setPushVlanAction(pushVlanAction.build()).build();
986     }
987
988     /**
989      * Method converts OF PushMpls action to SAL PushMpls action.
990      *
991      * @param action
992      * @return PushMplsAction
993      */
994     public static PushMplsActionCase ofToSALPushMplsAction(Action action) {
995
996         PushMplsActionBuilder pushMplsAction = new PushMplsActionBuilder();
997
998         EthertypeAction etherType = action.getAugmentation(EthertypeAction.class);
999         pushMplsAction.setEthernetType(etherType.getEthertype().getValue());
1000
1001         return new PushMplsActionCaseBuilder().setPushMplsAction(pushMplsAction.build()).build();
1002     }
1003
1004     /**
1005      * Method converts OF PopMpls action to SAL PopMpls action.
1006      *
1007      * @param action
1008      * @return PopMplsActionCase
1009      */
1010     public static PopMplsActionCase ofToSALPopMplsAction(Action action) {
1011
1012         PopMplsActionBuilder popMplsAction = new PopMplsActionBuilder();
1013
1014         EthertypeAction etherType = action.getAugmentation(EthertypeAction.class);
1015         popMplsAction.setEthernetType(etherType.getEthertype().getValue());
1016
1017         return new PopMplsActionCaseBuilder().setPopMplsAction(popMplsAction.build()).build();
1018     }
1019
1020     /**
1021      * Method converts OF SetQueue action to SAL SetQueue action.
1022      *
1023      * @param action
1024      * @return SetQueueAction
1025      */
1026     public static SetQueueActionCase ofToSALSetQueue(Action action) {
1027
1028         SetQueueActionBuilder setQueueAction = new SetQueueActionBuilder();
1029
1030         QueueIdAction queueId = action.getAugmentation(QueueIdAction.class);
1031         setQueueAction.setQueueId(queueId.getQueueId());
1032
1033         return new SetQueueActionCaseBuilder().setSetQueueAction(setQueueAction.build()).build();
1034     }
1035
1036     /**
1037      * Method converts OF SetNwTtl action to SAL SetNwTtl action.
1038      *
1039      * @param action
1040      * @return SetNwTtlAction
1041      */
1042     public static SetNwTtlActionCase ofToSALSetNwTtl(Action action) {
1043
1044         SetNwTtlActionBuilder setNwTtl = new SetNwTtlActionBuilder();
1045         NwTtlAction nwTtl = action.getAugmentation(NwTtlAction.class);
1046         setNwTtl.setNwTtl(nwTtl.getNwTtl());
1047
1048         return new SetNwTtlActionCaseBuilder().setSetNwTtlAction(setNwTtl.build()).build();
1049     }
1050
1051     /**
1052      * Method converts OF Pushvlan action to SAL PushVlan action.
1053      *
1054      * @param action
1055      * @return PushVlanAction
1056      */
1057     public static PushPbbActionCase ofToSALPushPbbAction(Action action) {
1058
1059         PushPbbActionBuilder pushPbbAction = new PushPbbActionBuilder();
1060
1061         EthertypeAction etherType = action.getAugmentation(EthertypeAction.class);
1062         pushPbbAction.setEthernetType(etherType.getEthertype().getValue());
1063
1064         return new PushPbbActionCaseBuilder().setPushPbbAction(pushPbbAction.build()).build();
1065     }
1066
1067 }