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