sanitize Boolean autoboxing NPE
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / sal / convertor / FlowConvertor.java
1 /**
2  * Copyright (c) 2013 Ericsson. 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
9 package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor;
10
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.List;
14
15 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.flowflag.FlowFlagReactor;
16 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchReactor;
17 import org.opendaylight.openflowplugin.openflow.md.util.ByteUtil;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.ActionList;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlow;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ClearActionsCase;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCase;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.MeterCase;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteActionsCase;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCase;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActions;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.clear.actions._case.ClearActions;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTable;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.meter._case.Meter;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.actions._case.WriteActions;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.metadata._case.WriteMetadata;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionsInstruction;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionsInstructionBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataInstruction;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataInstructionBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MeterIdInstruction;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MeterIdInstructionBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TableIdInstruction;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TableIdInstructionBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.ActionsList;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.Instructions;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.InstructionsBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModCommand;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MatchTypeBase;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableId;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OxmMatchType;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntries;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
56
57 import com.google.common.base.Objects;
58
59 /**
60  * Utility class for converting a MD-SAL Flow into the OF flow mod
61  */
62 public class FlowConvertor {
63     private static final Logger logger = LoggerFactory.getLogger(FlowConvertor.class);
64
65     // Default values for when things are null
66     private static final BigInteger DEFAULT_COOKIE = BigInteger.ZERO;
67     private static final BigInteger DEFAULT_COOKIE_MASK = BigInteger.ZERO;
68     private static final TableId DEFAULT_TABLE_ID = new TableId(new Long(0));
69     private static final Integer DEFAULT_IDLE_TIMEOUT = new Integer(5 * 60);
70     private static final Integer DEFAULT_HARD_TIMEOUT = new Integer(10 * 60);
71     private static final Integer DEFAULT_PRIORITY = Integer.parseInt("8000", 16);
72     private static final Long DEFAULT_BUFFER_ID = Long.parseLong("ffffffff", 16);
73     private static final Long OFPP_ANY = Long.parseLong("ffffffff", 16);
74     private static final Long DEFAULT_OUT_PORT = OFPP_ANY;
75     private static final Long OFPG_ANY = Long.parseLong("ffffffff", 16);
76     private static final Long DEFAULT_OUT_GROUP = OFPG_ANY;
77     /** flow flag: remove */
78     public static final boolean DEFAULT_OFPFF_FLOW_REM = true;
79     /** flow flag: check overlap */
80     public static final boolean DEFAULT_OFPFF_CHECK_OVERLAP = false;
81     /** flow flag: reset counts */
82     public static final boolean DEFAULT_OFPFF_RESET_COUNTS = false;
83     /** flow flag: don't keep track of packet counts */
84     public static final boolean DEFAULT_OFPFF_NO_PKT_COUNTS = false;
85     /** flow flag: don't keep track of byte counts */
86     public static final boolean DEFAULT_OFPFF_NO_BYT_COUNTS = false;
87     /** flow flag: emergency [OFP-1.0] */
88     public static final boolean DEFAULT_OFPFF_EMERGENCY = false;
89     /** OxmMatch type */
90     public static final Class<? extends MatchTypeBase> DEFAULT_MATCH_TYPE = OxmMatchType.class;
91     /** default match entries - empty */
92     public static final List<MatchEntries> DEFAULT_MATCH_ENTRIES = new ArrayList<MatchEntries>();
93
94     public static FlowModInput toFlowModInput(Flow flow, short version) {
95         FlowModInputBuilder flowMod = new FlowModInputBuilder();
96         if (flow.getCookie() != null) {
97             flowMod.setCookie(flow.getCookie());
98         } else {
99             flowMod.setCookie(DEFAULT_COOKIE);
100         }
101
102         if (flow.getCookieMask() != null) {
103             flowMod.setCookieMask(new BigInteger(flow.getCookieMask().toString()));
104         } else {
105             flowMod.setCookieMask(DEFAULT_COOKIE_MASK);
106         }
107
108         if (flow.getTableId() != null) {
109             flowMod.setTableId(new TableId(flow.getTableId().longValue()));
110         } else {
111             flowMod.setTableId(DEFAULT_TABLE_ID);
112         }
113
114         if (flow instanceof AddFlowInput) {
115             flowMod.setCommand(FlowModCommand.OFPFCADD);
116         } else if (flow instanceof RemoveFlowInput) {
117             if (Objects.firstNonNull(flow.isStrict(), Boolean.FALSE)) {
118                 flowMod.setCommand(FlowModCommand.OFPFCDELETESTRICT);
119             } else {
120                 flowMod.setCommand(FlowModCommand.OFPFCDELETE);
121             }
122         } else if (flow instanceof UpdatedFlow) {
123             if (Objects.firstNonNull(flow.isStrict(), Boolean.FALSE)) {
124                 flowMod.setCommand(FlowModCommand.OFPFCMODIFYSTRICT);
125             } else {
126                 flowMod.setCommand(FlowModCommand.OFPFCMODIFY);
127             }
128         }
129         if (flow.getIdleTimeout() != null) {
130             flowMod.setIdleTimeout(flow.getIdleTimeout());
131         } else {
132             flowMod.setIdleTimeout(DEFAULT_IDLE_TIMEOUT);
133         }
134         if (flow.getHardTimeout() != null) {
135             flowMod.setHardTimeout(flow.getHardTimeout());
136         } else {
137             flowMod.setHardTimeout(DEFAULT_HARD_TIMEOUT);
138         }
139         if (flow.getPriority() != null) {
140             flowMod.setPriority(flow.getPriority());
141         } else {
142             flowMod.setPriority(DEFAULT_PRIORITY);
143         }
144         if (flow.getBufferId() != null) {
145             flowMod.setBufferId(flow.getBufferId());
146         } else {
147             flowMod.setBufferId(DEFAULT_BUFFER_ID);
148         }
149
150         if (flow.getOutPort() != null) {
151             flowMod.setOutPort(new PortNumber(flow.getOutPort().longValue()));
152         } else {
153             flowMod.setOutPort(new PortNumber(DEFAULT_OUT_PORT));
154         }
155         if (flow.getOutGroup() != null) {
156             flowMod.setOutGroup(flow.getOutGroup());
157         } else {
158             flowMod.setOutGroup(DEFAULT_OUT_GROUP);
159         }
160
161         
162         // convert and inject flowFlags
163         FlowFlagReactor.getInstance().convert(flow.getFlags(), version, flowMod);
164
165         // convert and inject match
166         MatchReactor.getInstance().convert(flow.getMatch(), version, flowMod);
167
168         if (flow.getInstructions() != null) {
169             flowMod.setInstructions(toInstructions(flow.getInstructions(), version));
170             flowMod.setActionsList(getActionsList(flow.getInstructions(), version));
171         }
172         flowMod.setVersion(version);
173         
174         return flowMod.build();
175     }
176
177     private static List<Instructions> toInstructions(
178             org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions instructions,
179             short version) {
180         List<Instructions> instructionsList = new ArrayList<>();
181
182         for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction instruction : instructions
183                 .getInstruction()) {
184             InstructionsBuilder instructionBuilder = new InstructionsBuilder();
185             org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction curInstruction = instruction
186                     .getInstruction();
187             if (curInstruction instanceof GoToTableCase) {
188                 GoToTableCase goToTablecase = (GoToTableCase) curInstruction;
189                 GoToTable goToTable = goToTablecase.getGoToTable();
190                 instructionBuilder
191                         .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.GotoTable.class);
192                 TableIdInstructionBuilder tableBuilder = new TableIdInstructionBuilder();
193                 tableBuilder.setTableId(goToTable.getTableId());
194                 instructionBuilder.addAugmentation(TableIdInstruction.class, tableBuilder.build());
195                 instructionsList.add(instructionBuilder.build());
196             }
197
198             else if (curInstruction instanceof WriteMetadataCase) {
199                 WriteMetadataCase writeMetadatacase = (WriteMetadataCase) curInstruction;
200                 WriteMetadata writeMetadata = writeMetadatacase.getWriteMetadata();
201                 instructionBuilder
202                         .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteMetadata.class);
203                 MetadataInstructionBuilder metadataBuilder = new MetadataInstructionBuilder();
204                 metadataBuilder.setMetadata(ByteUtil.convertBigIntegerTo64Bit(writeMetadata.getMetadata()));
205                 metadataBuilder
206                         .setMetadataMask(ByteUtil.convertBigIntegerTo64Bit(writeMetadata.getMetadataMask()));
207                 instructionBuilder.addAugmentation(MetadataInstruction.class, metadataBuilder.build());
208                 instructionsList.add(instructionBuilder.build());
209             }
210
211             else if (curInstruction instanceof WriteActionsCase) {
212                 WriteActionsCase writeActionscase = (WriteActionsCase) curInstruction;
213                 WriteActions writeActions = writeActionscase.getWriteActions();
214                 instructionBuilder
215                         .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteActions.class);
216                 ActionsInstructionBuilder actionsInstructionBuilder = new ActionsInstructionBuilder();
217                 actionsInstructionBuilder.setActionsList(ActionConvertor.getActionList(writeActions.getAction(),
218                         version));
219                 instructionBuilder.addAugmentation(ActionsInstruction.class, actionsInstructionBuilder.build());
220                 instructionsList.add(instructionBuilder.build());
221             }
222
223             else if (curInstruction instanceof ApplyActionsCase) {
224                 ApplyActionsCase applyActionscase = (ApplyActionsCase) curInstruction;
225                 ApplyActions applyActions = applyActionscase.getApplyActions();
226                 instructionBuilder
227                         .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ApplyActions.class);
228                 ActionsInstructionBuilder actionsInstructionBuilder = new ActionsInstructionBuilder();
229                 actionsInstructionBuilder.setActionsList(ActionConvertor.getActionList(applyActions.getAction(),
230                         version));
231                 instructionBuilder.addAugmentation(ActionsInstruction.class, actionsInstructionBuilder.build());
232                 instructionsList.add(instructionBuilder.build());
233             }
234
235             else if (curInstruction instanceof ClearActionsCase) {
236                 ClearActionsCase clearActionscase = (ClearActionsCase) curInstruction;
237                 ClearActions clearActions = clearActionscase.getClearActions();
238                 instructionBuilder
239                         .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ClearActions.class);
240                 ActionsInstructionBuilder actionsInstructionBuilder = new ActionsInstructionBuilder();
241                 actionsInstructionBuilder.setActionsList(ActionConvertor.getActionList(clearActions.getAction(),
242                         version));
243                 instructionBuilder.addAugmentation(ActionsInstruction.class, actionsInstructionBuilder.build());
244                 instructionsList.add(instructionBuilder.build());
245             }
246
247             else if (curInstruction instanceof MeterCase) {
248                 MeterCase metercase = (MeterCase) curInstruction;
249                 Meter meter = metercase.getMeter();
250                 instructionBuilder
251                         .setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.Meter.class);
252                 MeterIdInstructionBuilder meterBuilder = new MeterIdInstructionBuilder();
253                 Long meterId = meter.getMeterId().getValue();
254                 meterBuilder.setMeterId(meterId);
255                 instructionBuilder.addAugmentation(MeterIdInstruction.class, meterBuilder.build());
256                 instructionsList.add(instructionBuilder.build());
257             }
258         }
259         return instructionsList;
260     }
261     
262     private static List<ActionsList> getActionsList(
263             org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions instructions,
264             short version) {
265
266         for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction instruction : instructions
267                 .getInstruction()) {
268             org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction curInstruction = instruction
269                     .getInstruction();
270
271             if (curInstruction instanceof ApplyActionsCase) {
272                 ApplyActionsCase applyActionscase = (ApplyActionsCase) curInstruction;
273                 ApplyActions applyActions = applyActionscase.getApplyActions();
274                 return ActionConvertor.getActionList(applyActions.getAction(), version);
275             }
276
277         }
278         return null;
279     }
280 }