2a73c8bbaa0b98e9d8bd890adf02f74404c0e5d5
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / sal / convertor / GroupConvertor.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 package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor;
9
10 import java.math.BigInteger;
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.Comparator;
14 import java.util.List;
15
16 import org.opendaylight.openflowjava.protocol.api.util.BinContent;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInput;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroup;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.Buckets;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupId;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupModCommand;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupType;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInputBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.buckets.grouping.BucketsList;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.buckets.grouping.BucketsListBuilder;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 /**
35  * This Utility class decodes the SAL - Group Mod Message and encodes into a OF
36  * Library for the OFPT_GROUP_MOD Message. Input:SAL Layer Group command data.
37  * Output:GroupModInput Message.
38  *
39  *
40  */
41 public final class GroupConvertor {
42
43     private static final Logger LOG = LoggerFactory.getLogger(GroupConvertor.class);
44
45     private static final Integer DEFAULT_WEIGHT = 0;
46     private static final Long OFPP_ANY = Long.parseLong("ffffffff", 16);
47     private static final Long DEFAULT_WATCH_PORT = OFPP_ANY;
48     private static final Long OFPG_ANY = Long.parseLong("ffffffff", 16);
49     private static final Long DEFAULT_WATCH_GROUP = OFPG_ANY;
50     private static final Comparator<Bucket> comparator = new Comparator<Bucket>(){
51         @Override
52         public int compare(Bucket bucket1,
53                            Bucket bucket2) {
54             if(bucket1.getBucketId() == null || bucket2.getBucketId() == null) return 0;
55             return  bucket1.getBucketId().getValue().compareTo(bucket2.getBucketId().getValue());
56         }
57     };
58
59     private GroupConvertor() {
60
61     }
62
63     public static GroupModInputBuilder toGroupModInput(
64
65     org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.Group source, short version,BigInteger datapathid) {
66         List<BucketsList> bucketLists = null;
67         GroupModInputBuilder groupModInputBuilder = new GroupModInputBuilder();
68         if (source instanceof AddGroupInput) {
69             groupModInputBuilder.setCommand(GroupModCommand.OFPGCADD);
70         } else if (source instanceof RemoveGroupInput) {
71             groupModInputBuilder.setCommand(GroupModCommand.OFPGCDELETE);
72         } else if (source instanceof UpdatedGroup) {
73             groupModInputBuilder.setCommand(GroupModCommand.OFPGCMODIFY);
74         }
75
76         if (GroupTypes.GroupAll.equals(source.getGroupType())) {
77             groupModInputBuilder.setType(GroupType.OFPGTALL);
78         }
79
80         if (GroupTypes.GroupSelect.equals(source.getGroupType())) {
81             groupModInputBuilder.setType(GroupType.OFPGTSELECT);
82         }
83
84         if (GroupTypes.GroupIndirect.equals(source.getGroupType())) {
85             groupModInputBuilder.setType(GroupType.OFPGTINDIRECT);
86         }
87
88         if (GroupTypes.GroupFf.equals(source.getGroupType())) {
89             groupModInputBuilder.setType(GroupType.OFPGTFF);
90         }
91
92         groupModInputBuilder.setGroupId(new GroupId(source.getGroupId().getValue()));
93         // Only if the bucket is configured for the group then add it
94         // During group deletion donot push the buckets
95         if(groupModInputBuilder.getCommand() != GroupModCommand.OFPGCDELETE) {
96             if ((source.getBuckets() != null) && (source.getBuckets().getBucket().size() != 0)) {
97
98                 Collections.sort(source.getBuckets().getBucket(), comparator);
99
100                 bucketLists = salToOFBucketList(source.getBuckets(), version, source.getGroupType().getIntValue(), datapathid);
101                 groupModInputBuilder.setBucketsList(bucketLists);
102             }
103         }
104         groupModInputBuilder.setVersion(version);
105         return groupModInputBuilder;
106
107     }
108
109     private static List<BucketsList> salToOFBucketList(Buckets buckets, short version, int groupType,BigInteger datapathid) {
110         final List<BucketsList> bucketLists = new ArrayList<>();
111         for (org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket groupBucket : buckets
112                 .getBucket()) {
113             BucketsListBuilder bucketBuilder = new BucketsListBuilder();
114
115             salToOFBucketListWeight(groupBucket, bucketBuilder, groupType);
116             salToOFBucketListWatchGroup(groupBucket, bucketBuilder, groupType);
117             salToOFBucketListWatchPort(groupBucket, bucketBuilder, groupType);
118
119             List<Action> bucketActionList = ActionConvertor.getActions(groupBucket.getAction(), version, datapathid, null);
120             bucketBuilder.setAction(bucketActionList);
121             BucketsList bucket = bucketBuilder.build();
122             bucketLists.add(bucket);
123         }
124         return bucketLists;
125
126     }
127
128     private static void salToOFBucketListWatchPort(Bucket groupBucket, BucketsListBuilder bucketBuilder, int groupType) {
129         if (null != groupBucket.getWatchPort()) {
130             bucketBuilder.setWatchPort(new PortNumber(groupBucket.getWatchPort()));
131         } else {
132             bucketBuilder.setWatchPort(new PortNumber(BinContent.intToUnsignedLong(DEFAULT_WATCH_PORT.intValue())));
133             if (groupType == GroupType.OFPGTFF.getIntValue()) {
134                 LOG.error("WatchPort required for this OFPGT_FF");
135             }
136         }
137     }
138
139     private static void salToOFBucketListWatchGroup(Bucket groupBucket, BucketsListBuilder bucketBuilder, int groupType) {
140         if (null != groupBucket.getWatchGroup()) {
141             bucketBuilder.setWatchGroup(groupBucket.getWatchGroup());
142         } else {
143             bucketBuilder.setWatchGroup(BinContent.intToUnsignedLong(DEFAULT_WATCH_GROUP.intValue()));
144             if (groupType == GroupType.OFPGTFF.getIntValue()) {
145                 LOG.error("WatchGroup required for this OFPGT_FF");
146             }
147         }
148     }
149
150     private static void salToOFBucketListWeight(Bucket groupBucket, BucketsListBuilder bucketBuilder, int groupType) {
151         if (null != groupBucket.getWeight()) {
152             bucketBuilder.setWeight(groupBucket.getWeight().intValue());
153         } else {
154             bucketBuilder.setWeight(DEFAULT_WEIGHT);
155             if (groupType == GroupType.OFPGTSELECT.getIntValue()) {
156                 LOG.error("Weight value required for this OFPGT_SELECT");
157             }
158         }
159     }
160
161 }