Adding IdManager/LockManager and related Changes
[vpnservice.git] / mdsalutil / mdsalutil-api / src / main / java / org / opendaylight / vpnservice / mdsalutil / MDSALUtil.java
1 /*
2  * Copyright (c) 2015 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
9 package org.opendaylight.vpnservice.mdsalutil;
10
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.HashMap;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.concurrent.ConcurrentHashMap;
17 import java.util.concurrent.ExecutionException;
18 import java.util.concurrent.LinkedBlockingQueue;
19
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCaseBuilder;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCaseBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActions;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.metadata._case.WriteMetadataBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.BucketId;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.Buckets;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.BucketsBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.BucketBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInputBuilder;
65 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
66 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
67 import org.opendaylight.yangtools.yang.binding.DataObject;
68 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
69 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
70 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
71 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
72 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
73 import org.slf4j.Logger;
74 import org.slf4j.LoggerFactory;
75
76 import com.google.common.base.Joiner;
77 import com.google.common.base.Optional;
78 import com.google.common.primitives.Bytes;
79 import com.google.common.primitives.Ints;
80 import com.google.common.util.concurrent.CheckedFuture;
81
82 public class MDSALUtil {
83
84     public static final String NODE_PREFIX = "openflow";
85     public static final String SEPARATOR = ":";
86     private static final Buckets EMPTY_Buckets = new BucketsBuilder().build();
87     private static final Instructions EMPTY_Instructions = new InstructionsBuilder().setInstruction(
88             new ArrayList<Instruction>()).build();
89     private static final Match EMPTY_Matches = new MatchBuilder().build();
90     private static final Logger logger = LoggerFactory.getLogger(MDSALUtil.class);
91
92     public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId, int priority, String flowName,
93             int idleTimeOut, int hardTimeOut, BigInteger cookie, List<MatchInfo> listMatchInfo,
94             List<InstructionInfo> listInstructionInfo) {
95
96         FlowEntity flowEntity = new FlowEntity(dpnId);
97
98         flowEntity.setTableId(tableId);
99         flowEntity.setFlowId(flowId);
100         flowEntity.setPriority(priority);
101         flowEntity.setFlowName(flowName);
102         flowEntity.setIdleTimeOut(idleTimeOut);
103         flowEntity.setHardTimeOut(hardTimeOut);
104         flowEntity.setCookie(cookie);
105         flowEntity.setMatchInfoList(listMatchInfo);
106         flowEntity.setInstructionInfoList(listInstructionInfo);
107
108         return flowEntity;
109     }
110
111     // TODO: CHECK IF THIS IS USED
112     public static Flow buildFlow(short tableId, String flowId, int priority, String flowName, int idleTimeOut,
113             int hardTimeOut, BigInteger cookie, List<MatchInfo> listMatchInfo, List<InstructionInfo> listInstructionInfo) {
114         return MDSALUtil.buildFlow(tableId, flowId, priority, flowName, idleTimeOut, hardTimeOut, cookie,
115                 listMatchInfo, listInstructionInfo, true);
116     }
117
118     public static Flow buildFlow(short tableId, String flowId, int priority, String flowName, int idleTimeOut,
119             int hardTimeOut, BigInteger cookie, List<MatchInfo> listMatchInfo,
120             List<InstructionInfo> listInstructionInfo, boolean isStrict) {
121         FlowKey key = new FlowKey(new FlowId(flowId));
122         return new FlowBuilder().setMatch(buildMatches(listMatchInfo)).setKey(key)
123                 .setPriority(Integer.valueOf(priority)).setInstructions(buildInstructions(listInstructionInfo))
124                 .setBarrier(false).setInstallHw(true).setHardTimeout(hardTimeOut).setIdleTimeout(idleTimeOut)
125                 .setFlowName(flowName).setTableId(Short.valueOf(tableId)).setStrict(isStrict)
126                 .setCookie(new FlowCookie(cookie)).build();
127     }
128
129     public static Flow buildFlowNew(short tableId, String flowId, int priority, String flowName, int idleTimeOut,
130                                  int hardTimeOut, BigInteger cookie, List<MatchInfo> listMatchInfo, List<Instruction> listInstructionInfo) {
131         return MDSALUtil.buildFlowNew(tableId, flowId, priority, flowName, idleTimeOut, hardTimeOut, cookie,
132                 listMatchInfo, listInstructionInfo, true);
133     }
134
135     private static Flow buildFlowNew(short tableId, String flowId, int priority, String flowName, int idleTimeOut,
136                                   int hardTimeOut, BigInteger cookie, List<MatchInfo> listMatchInfo,
137                                   List<Instruction> listInstructionInfo, boolean isStrict) {
138         FlowKey key = new FlowKey(new FlowId(flowId));
139         return new FlowBuilder().setMatch(buildMatches(listMatchInfo)).setKey(key)
140                 .setPriority(Integer.valueOf(priority)).setInstructions(new InstructionsBuilder().setInstruction(listInstructionInfo).build())
141                 .setBarrier(false).setInstallHw(true).setHardTimeout(hardTimeOut).setIdleTimeout(idleTimeOut)
142                 .setFlowName(flowName).setTableId(Short.valueOf(tableId)).setStrict(isStrict)
143                 .setCookie(new FlowCookie(cookie)).build();
144     }
145
146     public static GroupEntity buildGroupEntity(BigInteger dpnId, long groupId, String groupName, GroupTypes groupType,
147             List<BucketInfo> listBucketInfo) {
148
149         GroupEntity groupEntity = new GroupEntity(dpnId);
150
151         groupEntity.setGroupId(groupId);
152         groupEntity.setGroupName(groupName);
153         groupEntity.setGroupType(groupType);
154         groupEntity.setBucketInfoList(listBucketInfo);
155
156         return groupEntity;
157     }
158
159     public static TransmitPacketInput getPacketOutDefault(List<ActionInfo> actionInfos, byte[] payload, BigInteger dpnId) {
160         return new TransmitPacketInputBuilder()
161                 .setAction(buildActions(actionInfos))
162                 .setPayload(payload)
163                 .setNode(
164                         new NodeRef(InstanceIdentifier.builder(Nodes.class)
165                                 .child(Node.class, new NodeKey(new NodeId("openflow:" + dpnId))).toInstance()))
166                 .setIngress(getDefaultNodeConnRef(dpnId)).setEgress(getDefaultNodeConnRef(dpnId)).build();
167     }
168
169     public static TransmitPacketInput getPacketOut(List<ActionInfo> actionInfos, byte[] payload, long dpnId,
170             NodeConnectorRef ingress) {
171         return new TransmitPacketInputBuilder()
172                 .setAction(buildActions(actionInfos))
173                 .setPayload(payload)
174                 .setNode(
175                         new NodeRef(InstanceIdentifier.builder(Nodes.class)
176                                 .child(Node.class, new NodeKey(new NodeId("openflow:" + dpnId))).toInstance()))
177                 .setIngress(ingress).setEgress(ingress).build();
178     }
179
180     private static List<Action> buildActions(List<ActionInfo> actions) {
181         List<Action> actionsList = new ArrayList<Action>();
182         for (ActionInfo actionInfo : actions) {
183             actionsList.add(actionInfo.buildAction());
184         }
185         return actionsList;
186     }
187
188     public static String longToIp(long ip, long mask) {
189         StringBuilder sb = new StringBuilder(15);
190         Joiner joiner = Joiner.on('.');
191
192         joiner.appendTo(sb, Bytes.asList(Ints.toByteArray((int) ip)));
193
194         sb.append("/" + mask);
195
196         return sb.toString();
197     }
198
199     protected static Buckets buildBuckets(List<BucketInfo> listBucketInfo) {
200         long i = 0;
201         if (listBucketInfo != null) {
202             BucketsBuilder bucketsBuilder = new BucketsBuilder();
203             List<Bucket> bucketList = new ArrayList<Bucket>();
204
205             for (BucketInfo bucketInfo : listBucketInfo) {
206                 BucketBuilder bucketBuilder = new BucketBuilder();
207                 List<Action> actionsList = new ArrayList<Action>();
208
209                 bucketInfo.buildAndAddActions(actionsList);
210                 bucketBuilder.setAction(actionsList);
211                 bucketBuilder.setWeight(bucketInfo.getWeight());
212                 bucketBuilder.setBucketId(new BucketId(i++));
213                 bucketBuilder.setWeight(bucketInfo.getWeight()).setWatchPort(bucketInfo.getWatchPort())
214                         .setWatchGroup(bucketInfo.getWatchGroup());
215                 bucketList.add(bucketBuilder.build());
216             }
217
218             bucketsBuilder.setBucket(bucketList);
219             return bucketsBuilder.build();
220         }
221
222         return EMPTY_Buckets;
223     }
224
225     protected static Instructions buildInstructions(List<InstructionInfo> listInstructionInfo) {
226         if (listInstructionInfo != null) {
227             List<Instruction> instructions = new ArrayList<Instruction>();
228             int instructionKey = 0;
229
230             for (InstructionInfo instructionInfo : listInstructionInfo) {
231                 instructions.add(instructionInfo.buildInstruction(instructionKey));
232                 instructionKey++;
233             }
234
235             return new InstructionsBuilder().setInstruction(instructions).build();
236         }
237
238         return EMPTY_Instructions;
239     }
240
241     protected static Match buildMatches(List<MatchInfo> listMatchInfo) {
242         if (listMatchInfo != null) {
243             MatchBuilder matchBuilder = new MatchBuilder();
244             Map<Class<?>, Object> mapMatchBuilder = new HashMap<Class<?>, Object>();
245
246             for (MatchInfo matchInfo : listMatchInfo) {
247                 matchInfo.createInnerMatchBuilder(mapMatchBuilder);
248             }
249
250             for (MatchInfo matchInfo : listMatchInfo) {
251                 matchInfo.setMatch(matchBuilder, mapMatchBuilder);
252             }
253
254             return matchBuilder.build();
255         }
256
257         return EMPTY_Matches;
258     }
259
260     // TODO: Check the port const
261     public static NodeConnectorRef getDefaultNodeConnRef(BigInteger nDpId) {
262         return getNodeConnRef(NODE_PREFIX + SEPARATOR + nDpId, "0xfffffffd");
263     }
264
265     public static NodeConnectorRef getNodeConnRef(BigInteger nDpId, String port) {
266         return getNodeConnRef(NODE_PREFIX + SEPARATOR + nDpId, port);
267     }
268
269     public static NodeConnectorRef getNodeConnRef(String sNodeId, String port) {
270         String sNodeConnectorKey;
271         StringBuilder sbTmp;
272         NodeId nodeId;
273         NodeKey nodeKey;
274         NodeConnectorId nodeConnectorId;
275         NodeConnectorKey nodeConnectorKey;
276         InstanceIdentifierBuilder<Nodes> nodesInstanceIdentifierBuilder;
277         InstanceIdentifierBuilder<Node> nodeInstanceIdentifierBuilder;
278         InstanceIdentifierBuilder<NodeConnector> nodeConnectorInstanceIdentifierBuilder;
279         InstanceIdentifier<NodeConnector> nodeConnectorInstanceIdentifier;
280         NodeConnectorRef nodeConnectorRef;
281
282         sbTmp = new StringBuilder();
283
284         sbTmp.append(sNodeId);
285         sbTmp.append(SEPARATOR);
286         sbTmp.append(port);
287
288         sNodeConnectorKey = sbTmp.toString();
289         nodeConnectorId = new NodeConnectorId(sNodeConnectorKey);
290         nodeConnectorKey = new NodeConnectorKey(nodeConnectorId);
291
292         nodeId = new NodeId(sNodeId);
293         nodeKey = new NodeKey(nodeId);
294
295         nodesInstanceIdentifierBuilder = InstanceIdentifier.<Nodes> builder(Nodes.class);
296         nodeInstanceIdentifierBuilder = nodesInstanceIdentifierBuilder.<Node, NodeKey> child(Node.class, nodeKey);
297         nodeConnectorInstanceIdentifierBuilder = nodeInstanceIdentifierBuilder.<NodeConnector, NodeConnectorKey> child(
298                 NodeConnector.class, nodeConnectorKey);
299         nodeConnectorInstanceIdentifier = nodeConnectorInstanceIdentifierBuilder.toInstance();
300         nodeConnectorRef = new NodeConnectorRef(nodeConnectorInstanceIdentifier);
301         return nodeConnectorRef;
302     }
303
304     public static BigInteger getDpnIdFromNodeName(NodeId nodeId) {
305         return getDpnIdFromNodeName(nodeId.getValue());
306     }
307
308     public static BigInteger getDpnIdFromNodeName(String sMdsalNodeName) {
309         String sDpId = sMdsalNodeName.substring(sMdsalNodeName.lastIndexOf(":") + 1);
310         return new BigInteger(sDpId);
311     }
312
313     public static long getOfPortNumberFromPortName(NodeConnectorId nodeConnectorId) {
314         return getOfPortNumberFromPortName(nodeConnectorId.getValue());
315     }
316
317     public static long getOfPortNumberFromPortName(String sMdsalPortName) {
318         String sPortNumber = sMdsalPortName.substring(sMdsalPortName.lastIndexOf(":") + 1);
319         return Long.parseLong(sPortNumber);
320     }
321
322     public static TransmitPacketInput getPacketOut(List<ActionInfo> actionInfos, byte[] payload, BigInteger dpnId,
323                     NodeConnectorRef nodeConnRef) {
324         // TODO Auto-generated method stub
325         return null;
326     }
327
328     public static Instruction buildAndGetPopVlanActionInstruction(int actionKey, int instructionKey) {
329         Action popVlanAction = new ActionBuilder().setAction(
330                 new PopVlanActionCaseBuilder().setPopVlanAction(new PopVlanActionBuilder().build()).build())
331                 .setKey(new ActionKey(actionKey)).build();
332         List<Action> listAction = new ArrayList<Action> ();
333         listAction.add(popVlanAction);
334         ApplyActions applyActions = new ApplyActionsBuilder().setAction(listAction).build();
335         ApplyActionsCase applyActionsCase = new ApplyActionsCaseBuilder().setApplyActions(applyActions).build();
336         InstructionBuilder instructionBuilder = new InstructionBuilder();
337
338         instructionBuilder.setInstruction(applyActionsCase);
339         instructionBuilder.setKey(new InstructionKey(instructionKey));
340         return instructionBuilder.build();
341     }
342
343     public static Instruction buildAndGetWriteMetadaInstruction(BigInteger metadata,
344                                                                 BigInteger mask, int instructionKey) {
345         return new InstructionBuilder()
346                 .setInstruction(
347                         new WriteMetadataCaseBuilder().setWriteMetadata(
348                                 new WriteMetadataBuilder().setMetadata(metadata).setMetadataMask(mask).build())
349                                 .build()).setKey(new InstructionKey(instructionKey)).build();
350     }
351
352     public static <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
353                                                           InstanceIdentifier<T> path, DataBroker broker) {
354
355         ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
356
357         Optional<T> result = Optional.absent();
358         try {
359             result = tx.read(datastoreType, path).get();
360         } catch (Exception e) {
361             logger.error("An error occured while reading data from the path {} with the exception {}", path, e);
362         }
363         return result;
364     }
365
366     public static <T extends DataObject> Optional<T> read(DataBroker broker,
367                                                           LogicalDatastoreType datastoreType, InstanceIdentifier<T> path) {
368
369         ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
370
371         Optional<T> result = Optional.absent();
372         try {
373             result = tx.read(datastoreType, path).get();
374         } catch (Exception e) {
375             throw new RuntimeException(e);
376         }
377
378         return result;
379     }
380
381     public static <T extends DataObject> void syncWrite(DataBroker broker,
382                                                         LogicalDatastoreType datastoreType, InstanceIdentifier<T> path,
383                                                         T data) {
384         WriteTransaction tx = broker.newWriteOnlyTransaction();
385         tx.put(datastoreType, path, data, true);
386         CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
387         try {
388             futures.get();
389         } catch (InterruptedException | ExecutionException e) {
390             logger.error("Error writing to datastore (path, data) : ({}, {})", path, data);
391             throw new RuntimeException(e.getMessage());
392         }
393     }
394
395     public static <T extends DataObject> void syncUpdate(DataBroker broker,
396                                                          LogicalDatastoreType datastoreType, InstanceIdentifier<T> path,
397                                                          T data) {
398         WriteTransaction tx = broker.newWriteOnlyTransaction();
399         tx.merge(datastoreType, path, data, true);
400         CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
401         try {
402             futures.get();
403         } catch (InterruptedException | ExecutionException e) {
404             logger.error("Error writing to datastore (path, data) : ({}, {})", path, data);
405             throw new RuntimeException(e.getMessage());
406         }
407     }
408
409     public static <T extends DataObject> void syncDelete(DataBroker broker,
410                                                          LogicalDatastoreType datastoreType, InstanceIdentifier<T> obj) {
411         WriteTransaction tx = broker.newWriteOnlyTransaction();
412         tx.delete(datastoreType, obj);
413         CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
414         try {
415             futures.get();
416         } catch (InterruptedException | ExecutionException e) {
417             logger.error("Error deleting from datastore (path) : ({})", obj);
418             throw new RuntimeException(e.getMessage());
419         }
420     }
421 }