MD-SAL Statistics Manager- Implemented rpc/notification calls for group/meter statistics
[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.GroupFeatures.Capabilities;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupFeatures.Types;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterConfigStatsUpdatedBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterFeaturesUpdatedBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterStatisticsUpdatedBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroup;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDesc;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupFeatures;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeter;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfig;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeatures;
32 import org.opendaylight.yangtools.yang.binding.DataObject;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 /**
37  * Class converts multipart reply messages to the notification objects defined
38  * by statistics provider (manager ).
39  * 
40  * @author avishnoi@in.ibm.com
41  *
42  */
43 public class MultipartReplyTranslator implements IMDMessageTranslator<OfHeader,  List<DataObject>> {
44
45     protected static final Logger logger = LoggerFactory
46             .getLogger(MultipartReplyTranslator.class);
47     
48     private static GroupStatsResponseConvertor groupStatsConvertor = new GroupStatsResponseConvertor();
49     private static MeterStatsResponseConvertor meterStatsConvertor = new MeterStatsResponseConvertor();
50
51     @Override
52     public  List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sc, OfHeader msg) {
53         
54         List<DataObject> listDataObject = new CopyOnWriteArrayList<DataObject>();
55
56         if(msg instanceof MultipartReplyMessage){
57             MultipartReplyMessage mpReply = (MultipartReplyMessage)msg;
58             NodeId node = this.nodeIdFromDatapathId(sc.getFeatures().getDatapathId());
59             switch (mpReply.getType()){
60             case OFPMPGROUP:{
61                 logger.info("Received group statistics multipart reponse");
62                 GroupStatisticsUpdatedBuilder message = new GroupStatisticsUpdatedBuilder();
63                 message.setId(node);
64                 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
65                 message.setTransactionId(generateTransactionId(mpReply.getXid()));
66                 MultipartReplyGroup replyBody = (MultipartReplyGroup)mpReply.getMultipartReplyBody();
67                 message.setGroupStats(groupStatsConvertor.toSALGroupStatsList(replyBody.getGroupStats()));
68                 logger.debug("Converted group statistics : {}",message.toString());
69                 listDataObject.add(message.build());
70                 return listDataObject;
71             }
72             case OFPMPGROUPDESC:{
73                 logger.info("Received group description statistics multipart reponse");
74                 
75                 GroupDescStatsUpdatedBuilder message = new GroupDescStatsUpdatedBuilder();
76                 message.setId(node);
77                 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
78                 message.setTransactionId(generateTransactionId(mpReply.getXid()));
79                 MultipartReplyGroupDesc replyBody = (MultipartReplyGroupDesc)mpReply.getMultipartReplyBody();
80                 message.setGroupDescStats(groupStatsConvertor.toSALGroupDescStatsList(replyBody.getGroupDesc()));
81                 logger.debug("Converted group statistics : {}",message.toString());
82                 listDataObject.add(message.build());
83                 return listDataObject;
84             }
85             case OFPMPGROUPFEATURES: {
86                 logger.info("Received group features multipart reponse");
87                 GroupFeaturesUpdatedBuilder message = new GroupFeaturesUpdatedBuilder();
88                 message.setId(node);
89                 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
90                 message.setTransactionId(generateTransactionId(mpReply.getXid()));
91                 MultipartReplyGroupFeatures replyBody = (MultipartReplyGroupFeatures)mpReply.getMultipartReplyBody();
92                 message.setTypes(new Types(replyBody.getTypes().isOFPGTALL(),
93                                             replyBody.getTypes().isOFPGTSELECT(),
94                                             replyBody.getTypes().isOFPGTINDIRECT(),
95                                             replyBody.getTypes().isOFPGTSELECT()));
96                 message.setMaxGroups(replyBody.getMaxGroups());
97                 message.setCapabilities(new Capabilities(replyBody.getCapabilities().isOFPGFCCHAINING(),
98                         replyBody.getCapabilities().isOFPGFCCHAININGCHECKS(),
99                         replyBody.getCapabilities().isOFPGFCSELECTLIVENESS(),
100                         replyBody.getCapabilities().isOFPGFCSELECTWEIGHT()));
101                 
102                 message.setActions(getGroupActionsSupportBitmap(replyBody.getActionsBitmap()));
103                 listDataObject.add(message.build());
104                 return listDataObject;
105             }
106             case OFPMPMETER: {
107                 logger.info("Received meter statistics multipart reponse");
108                 MeterStatisticsUpdatedBuilder message = new MeterStatisticsUpdatedBuilder();
109                 message.setId(node);
110                 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
111                 message.setTransactionId(generateTransactionId(mpReply.getXid()));
112                 
113                 MultipartReplyMeter replyBody = (MultipartReplyMeter)mpReply.getMultipartReplyBody();
114                 message.setMeterStats(meterStatsConvertor.toSALMeterStatsList(replyBody.getMeterStats()));
115
116                 listDataObject.add(message.build());
117                 return listDataObject;
118             }
119             case OFPMPMETERCONFIG:{
120                 logger.info("Received meter config statistics multipart reponse");
121                 
122                 MeterConfigStatsUpdatedBuilder message = new MeterConfigStatsUpdatedBuilder();
123                 message.setId(node);
124                 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
125                 message.setTransactionId(generateTransactionId(mpReply.getXid()));
126                 
127                 MultipartReplyMeterConfig replyBody = (MultipartReplyMeterConfig)mpReply.getMultipartReplyBody();
128                 message.setMeterConfigStats(meterStatsConvertor.toSALMeterConfigList(replyBody.getMeterConfig()));
129                 listDataObject.add(message.build());
130                 return listDataObject;
131             }
132             case OFPMPMETERFEATURES:{
133                 logger.info("Received meter features multipart reponse");
134                 
135                 MeterFeaturesUpdatedBuilder message = new MeterFeaturesUpdatedBuilder();
136                 message.setId(node);
137                 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
138                 message.setTransactionId(generateTransactionId(mpReply.getXid()));
139                 
140                 MultipartReplyMeterFeatures replyBody = (MultipartReplyMeterFeatures)mpReply.getMultipartReplyBody();
141                 message.setMaxBands(replyBody.getMaxBands());
142                 message.setMaxColor(replyBody.getMaxColor());
143                 message.setMaxMeter(new Counter32(replyBody.getMaxMeter()));
144                 message.setCapabilities(new Counter32(getMeterBandCapabilityBitmap(replyBody.getCapabilities())));
145                 
146                  // TODO: Band Types is bitmaps, but plugin is receiving enum.
147                  
148                 //message.setBandTypes(replyBody.getBandTypes())
149                 listDataObject.add(message.build());
150                 return listDataObject;
151             }
152             default:
153                 logger.info(" Type : {}, not handled yet",mpReply.getType().name() );
154                 return listDataObject;
155             }
156         }
157         
158         return listDataObject;
159     }
160     
161     private NodeId nodeIdFromDatapathId(BigInteger datapathId) {
162         String current = datapathId.toString();
163         return new NodeId("openflow:" + current);
164     }
165     
166     private TransactionId generateTransactionId(Long xid){
167         String stringXid =xid.toString();
168         BigInteger bigIntXid = new BigInteger( stringXid );
169         return new TransactionId(bigIntXid);
170
171     }
172
173     /* 
174      * Method returns the bitmap of actions supported by each group.
175      * TODO: My recommendation would be, its good to have a respective model of 
176      * 'type bits', which will generate a class where all these flags will eventually
177      * be stored as boolean. It will be convenient for application to check the
178      * supported action, rather then doing bitmap operation.
179      * @param actionsSupported
180      * @return
181      */
182     private List<Long> getGroupActionsSupportBitmap(List<org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionType> actionsSupported){
183         List<Long> supportActionByGroups = new ArrayList<Long>();
184         for(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionType supportedActions : actionsSupported){
185             long supportActionBitmap = 0;
186             supportActionBitmap |= supportedActions.isOFPATOUTPUT()?(1 << 0): ~(1 << 0);
187             supportActionBitmap |= supportedActions.isOFPATCOPYTTLOUT()?(1 << 11): ~(1 << 11);
188             supportActionBitmap |= supportedActions.isOFPATCOPYTTLIN()?(1 << 12): ~(1 << 12);
189             supportActionBitmap |= supportedActions.isOFPATSETMPLSTTL()?(1 << 15): ~(1 << 15);
190             supportActionBitmap |= supportedActions.isOFPATDECMPLSTTL()?(1 << 16): ~(1 << 16);
191             supportActionBitmap |= supportedActions.isOFPATPUSHVLAN()?(1 << 16): ~(1 << 16);
192             supportActionBitmap |= supportedActions.isOFPATPOPVLAN()?(1 << 17): ~(1 << 17);
193             supportActionBitmap |= supportedActions.isOFPATPUSHMPLS()?(1 << 18): ~(1 << 18);
194             supportActionBitmap |= supportedActions.isOFPATPOPMPLS()?(1 << 19): ~(1 << 19);
195             supportActionBitmap |= supportedActions.isOFPATSETQUEUE()?(1 << 20): ~(1 << 20);
196             supportActionBitmap |= supportedActions.isOFPATGROUP()?(1 << 21): ~(1 << 21);
197             supportActionBitmap |= supportedActions.isOFPATSETNWTTL()?(1 << 22): ~(1 << 22);
198             supportActionBitmap |= supportedActions.isOFPATDECNWTTL()?(1 << 23): ~(1 << 23);
199             supportActionBitmap |= supportedActions.isOFPATSETFIELD()?(1 << 24): ~(1 << 24);
200             supportActionBitmap |= supportedActions.isOFPATPUSHPBB()?(1 << 25): ~(1 << 25);
201             supportActionBitmap |= supportedActions.isOFPATPOPPBB()?(1 << 26): ~(1 << 26);
202             supportActionBitmap |= supportedActions.isOFPATEXPERIMENTER()?(1 << 27): ~(1 << 27);
203             supportActionByGroups.add(new Long(supportActionBitmap));
204         }
205         return supportActionByGroups;
206     }
207     /*
208      * Method returns Capability Bitmap of the meter band.
209      * TODO: I would recommend to use the 'type bits' model to store 
210      * the bitmap for the same reason as i given above for method  
211      * getGroupActionsSupportBitmap.
212      * @param capabilityFlags
213      * @return
214      */
215     
216     private long getMeterBandCapabilityBitmap (org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterFlags capabilityFlags){
217         long capabilityBitmap = 0;
218         capabilityBitmap |= capabilityFlags.isOFPMFKBPS()?(1 << 0): ~(1 << 0);
219         capabilityBitmap |= capabilityFlags.isOFPMFPKTPS()?(1 << 1): ~(1 << 1);
220         capabilityBitmap |= capabilityFlags.isOFPMFBURST()?(1 << 2): ~(1 << 2);
221         capabilityBitmap |= capabilityFlags.isOFPMFSTATS()?(1 << 3): ~(1 << 3);
222         return capabilityBitmap;
223     }
224
225 }