MD-SAL Statistics Manager - Did the code changes that is needed to work with commit...
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / translator / MultipartReplyTranslator.java
1 package org.opendaylight.openflowplugin.openflow.md.core.translator;
2
3 import java.math.BigInteger;
4 import java.util.ArrayList;
5 import java.util.List;
6 import java.util.concurrent.CopyOnWriteArrayList;
7
8 import org.opendaylight.openflowplugin.openflow.md.core.IMDMessageTranslator;
9 import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
10 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.GroupStatsResponseConvertor;
11 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.MeterStatsResponseConvertor;
12 import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext;
13 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.Counter32;
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdatedBuilder;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupFeaturesUpdatedBuilder;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdatedBuilder;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.Chaining;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.ChainingChecks;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupAll;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupCapability;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupFf;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupIndirect;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupSelect;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupType;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.SelectLiveness;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.SelectWeight;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterConfigStatsUpdatedBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterFeaturesUpdatedBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterStatisticsUpdatedBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBand;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandDrop;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandDscpRemark;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBurst;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterCapability;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterKbps;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterPktps;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterStats;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroup;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDesc;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupFeatures;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeter;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfig;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeatures;
48 import org.opendaylight.yangtools.yang.binding.DataObject;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52 /**
53  * Class converts multipart reply messages to the notification objects defined
54  * by statistics provider (manager ).
55  * 
56  * @author avishnoi@in.ibm.com
57  *
58  */
59 public class MultipartReplyTranslator implements IMDMessageTranslator<OfHeader,  List<DataObject>> {
60
61     protected static final Logger logger = LoggerFactory
62             .getLogger(MultipartReplyTranslator.class);
63     
64     private static GroupStatsResponseConvertor groupStatsConvertor = new GroupStatsResponseConvertor();
65     private static MeterStatsResponseConvertor meterStatsConvertor = new MeterStatsResponseConvertor();
66
67     @Override
68     public  List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sc, OfHeader msg) {
69         
70         List<DataObject> listDataObject = new CopyOnWriteArrayList<DataObject>();
71
72         if(msg instanceof MultipartReplyMessage){
73             MultipartReplyMessage mpReply = (MultipartReplyMessage)msg;
74             NodeId node = this.nodeIdFromDatapathId(sc.getFeatures().getDatapathId());
75             switch (mpReply.getType()){
76             case OFPMPGROUP:{
77                 logger.info("Received group statistics multipart reponse");
78                 GroupStatisticsUpdatedBuilder message = new GroupStatisticsUpdatedBuilder();
79                 message.setId(node);
80                 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
81                 message.setTransactionId(generateTransactionId(mpReply.getXid()));
82                 MultipartReplyGroup replyBody = (MultipartReplyGroup)mpReply.getMultipartReplyBody();
83                 message.setGroupStats(groupStatsConvertor.toSALGroupStatsList(replyBody.getGroupStats()));
84                 logger.debug("Converted group statistics : {}",message.toString());
85                 listDataObject.add(message.build());
86                 return listDataObject;
87             }
88             case OFPMPGROUPDESC:{
89                 logger.info("Received group description statistics multipart reponse");
90                 
91                 GroupDescStatsUpdatedBuilder message = new GroupDescStatsUpdatedBuilder();
92                 message.setId(node);
93                 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
94                 message.setTransactionId(generateTransactionId(mpReply.getXid()));
95                 MultipartReplyGroupDesc replyBody = (MultipartReplyGroupDesc)mpReply.getMultipartReplyBody();
96                 message.setGroupDescStats(groupStatsConvertor.toSALGroupDescStatsList(replyBody.getGroupDesc()));
97                 logger.debug("Converted group statistics : {}",message.toString());
98                 listDataObject.add(message.build());
99                 return listDataObject;
100             }
101             case OFPMPGROUPFEATURES: {
102                 logger.info("Received group features multipart reponse");
103                 GroupFeaturesUpdatedBuilder message = new GroupFeaturesUpdatedBuilder();
104                 message.setId(node);
105                 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
106                 message.setTransactionId(generateTransactionId(mpReply.getXid()));
107                 MultipartReplyGroupFeatures replyBody = (MultipartReplyGroupFeatures)mpReply.getMultipartReplyBody();
108                 List<Class<? extends GroupType>> supportedGroups = 
109                         new ArrayList<Class<? extends GroupType>>();
110                 
111                 if(replyBody.getTypes().isOFPGTALL()){
112                     supportedGroups.add(GroupAll.class);
113                 }
114                 if(replyBody.getTypes().isOFPGTSELECT()){
115                     supportedGroups.add(GroupSelect.class);
116                 }
117                 if(replyBody.getTypes().isOFPGTINDIRECT()){
118                     supportedGroups.add(GroupIndirect.class);
119                 }
120                 if(replyBody.getTypes().isOFPGTFF()){
121                     supportedGroups.add(GroupFf.class);
122                 }
123                 message.setGroupTypesSupported(supportedGroups);
124                 message.setMaxGroups(replyBody.getMaxGroups());
125                 
126                 List<Class<? extends GroupCapability>> supportedCapabilities = 
127                         new ArrayList<Class<? extends GroupCapability>>();
128                 
129                 if(replyBody.getCapabilities().isOFPGFCCHAINING()){
130                     supportedCapabilities.add(Chaining.class);
131                 }
132                 if(replyBody.getCapabilities().isOFPGFCCHAININGCHECKS()){
133                     supportedCapabilities.add(ChainingChecks.class);
134                 }
135                 if(replyBody.getCapabilities().isOFPGFCSELECTLIVENESS()){
136                     supportedCapabilities.add(SelectLiveness.class);
137                 }
138                 if(replyBody.getCapabilities().isOFPGFCSELECTWEIGHT()){
139                     supportedCapabilities.add(SelectWeight.class);
140                 }
141
142                 message.setGroupCapabilitiesSupported(supportedCapabilities);
143                 
144                 message.setActions(getGroupActionsSupportBitmap(replyBody.getActionsBitmap()));
145                 listDataObject.add(message.build());
146
147                 //augmentGroupFeaturesToNode(message);
148                 
149                 //Send update notification to all the listeners 
150                 return listDataObject;
151             }
152             case OFPMPMETER: {
153                 logger.info("Received meter statistics multipart reponse");
154                 MeterStatisticsUpdatedBuilder message = new MeterStatisticsUpdatedBuilder();
155                 message.setId(node);
156                 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
157                 message.setTransactionId(generateTransactionId(mpReply.getXid()));
158                 
159                 MultipartReplyMeter replyBody = (MultipartReplyMeter)mpReply.getMultipartReplyBody();
160                 message.setMeterStats(meterStatsConvertor.toSALMeterStatsList(replyBody.getMeterStats()));
161
162                 listDataObject.add(message.build());
163                 return listDataObject;
164             }
165             case OFPMPMETERCONFIG:{
166                 logger.info("Received meter config statistics multipart reponse");
167                 
168                 MeterConfigStatsUpdatedBuilder message = new MeterConfigStatsUpdatedBuilder();
169                 message.setId(node);
170                 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
171                 message.setTransactionId(generateTransactionId(mpReply.getXid()));
172                 
173                 MultipartReplyMeterConfig replyBody = (MultipartReplyMeterConfig)mpReply.getMultipartReplyBody();
174                 message.setMeterConfigStats(meterStatsConvertor.toSALMeterConfigList(replyBody.getMeterConfig()));
175                 listDataObject.add(message.build());
176                 return listDataObject;
177             }
178             case OFPMPMETERFEATURES:{
179                 logger.info("Received meter features multipart reponse");
180                 //Convert OF message and send it to SAL listener
181                 MeterFeaturesUpdatedBuilder message = new MeterFeaturesUpdatedBuilder();
182                 message.setId(node);
183                 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
184                 message.setTransactionId(generateTransactionId(mpReply.getXid()));
185                 
186                 MultipartReplyMeterFeatures replyBody = (MultipartReplyMeterFeatures)mpReply.getMultipartReplyBody();
187                 message.setMaxBands(replyBody.getMaxBands());
188                 message.setMaxColor(replyBody.getMaxColor());
189                 message.setMaxMeter(new Counter32(replyBody.getMaxMeter()));
190                 
191                 List<Class<? extends MeterCapability>> supportedCapabilities = 
192                         new ArrayList<Class<? extends MeterCapability>>();
193                 if(replyBody.getCapabilities().isOFPMFBURST()){
194                     supportedCapabilities.add(MeterBurst.class);
195                 }
196                 if(replyBody.getCapabilities().isOFPMFKBPS()){
197                     supportedCapabilities.add(MeterKbps.class);
198                     
199                 }
200                 if(replyBody.getCapabilities().isOFPMFPKTPS()){
201                     supportedCapabilities.add(MeterPktps.class);
202                     
203                 }
204                 if(replyBody.getCapabilities().isOFPMFSTATS()){
205                     supportedCapabilities.add(MeterStats.class);
206                     
207                 }
208                 message.setMeterCapabilitiesSupported(supportedCapabilities);
209                 
210                 List<Class<? extends MeterBand>> supportedMeterBand = 
211                         new ArrayList<Class <? extends MeterBand>>();
212                 if(replyBody.getBandTypes().isOFPMBTDROP()){
213                     supportedMeterBand.add(MeterBandDrop.class);
214                 }
215                 if(replyBody.getBandTypes().isOFPMBTDSCPREMARK()){
216                     supportedMeterBand.add(MeterBandDscpRemark.class);
217                 }
218                 message.setMeterBandSupported(supportedMeterBand);
219                 listDataObject.add(message.build());
220
221                 //augmentMeterFeaturesToNode(message);
222
223                 //Send update notification to all the listeners 
224                 return listDataObject;
225             }
226             default:
227                 logger.info(" Type : {}, not handled yet",mpReply.getType().name() );
228                 return listDataObject;
229             }
230         }
231         
232         return listDataObject;
233     }
234     
235     private NodeId nodeIdFromDatapathId(BigInteger datapathId) {
236         String current = datapathId.toString();
237         return new NodeId("openflow:" + current);
238     }
239     
240     private TransactionId generateTransactionId(Long xid){
241         String stringXid =xid.toString();
242         BigInteger bigIntXid = new BigInteger( stringXid );
243         return new TransactionId(bigIntXid);
244
245     }
246
247     /* 
248      * Method returns the bitmap of actions supported by each group.
249      * TODO: My recommendation would be, its good to have a respective model of 
250      * 'type bits', which will generate a class where all these flags will eventually
251      * be stored as boolean. It will be convenient for application to check the
252      * supported action, rather then doing bitmap operation.
253      * @param actionsSupported
254      * @return
255      */
256     private List<Long> getGroupActionsSupportBitmap(List<org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionType> actionsSupported){
257         List<Long> supportActionByGroups = new ArrayList<Long>();
258         for(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionType supportedActions : actionsSupported){
259             long supportActionBitmap = 0;
260             supportActionBitmap |= supportedActions.isOFPATOUTPUT()?(1 << 0): ~(1 << 0);
261             supportActionBitmap |= supportedActions.isOFPATCOPYTTLOUT()?(1 << 11): ~(1 << 11);
262             supportActionBitmap |= supportedActions.isOFPATCOPYTTLIN()?(1 << 12): ~(1 << 12);
263             supportActionBitmap |= supportedActions.isOFPATSETMPLSTTL()?(1 << 15): ~(1 << 15);
264             supportActionBitmap |= supportedActions.isOFPATDECMPLSTTL()?(1 << 16): ~(1 << 16);
265             supportActionBitmap |= supportedActions.isOFPATPUSHVLAN()?(1 << 16): ~(1 << 16);
266             supportActionBitmap |= supportedActions.isOFPATPOPVLAN()?(1 << 17): ~(1 << 17);
267             supportActionBitmap |= supportedActions.isOFPATPUSHMPLS()?(1 << 18): ~(1 << 18);
268             supportActionBitmap |= supportedActions.isOFPATPOPMPLS()?(1 << 19): ~(1 << 19);
269             supportActionBitmap |= supportedActions.isOFPATSETQUEUE()?(1 << 20): ~(1 << 20);
270             supportActionBitmap |= supportedActions.isOFPATGROUP()?(1 << 21): ~(1 << 21);
271             supportActionBitmap |= supportedActions.isOFPATSETNWTTL()?(1 << 22): ~(1 << 22);
272             supportActionBitmap |= supportedActions.isOFPATDECNWTTL()?(1 << 23): ~(1 << 23);
273             supportActionBitmap |= supportedActions.isOFPATSETFIELD()?(1 << 24): ~(1 << 24);
274             supportActionBitmap |= supportedActions.isOFPATPUSHPBB()?(1 << 25): ~(1 << 25);
275             supportActionBitmap |= supportedActions.isOFPATPOPPBB()?(1 << 26): ~(1 << 26);
276             supportActionBitmap |= supportedActions.isOFPATEXPERIMENTER()?(1 << 27): ~(1 << 27);
277             supportActionByGroups.add(new Long(supportActionBitmap));
278         }
279         return supportActionByGroups;
280     }
281
282 }