1 package org.opendaylight.openflowplugin.openflow.md.core.translator;
3 import java.math.BigInteger;
4 import java.util.ArrayList;
6 import java.util.concurrent.CopyOnWriteArrayList;
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;
37 * Class converts multipart reply messages to the notification objects defined
38 * by statistics provider (manager ).
40 * @author avishnoi@in.ibm.com
43 public class MultipartReplyTranslator implements IMDMessageTranslator<OfHeader, List<DataObject>> {
45 protected static final Logger logger = LoggerFactory
46 .getLogger(MultipartReplyTranslator.class);
48 private static GroupStatsResponseConvertor groupStatsConvertor = new GroupStatsResponseConvertor();
49 private static MeterStatsResponseConvertor meterStatsConvertor = new MeterStatsResponseConvertor();
52 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sc, OfHeader msg) {
54 List<DataObject> listDataObject = new CopyOnWriteArrayList<DataObject>();
56 if(msg instanceof MultipartReplyMessage){
57 MultipartReplyMessage mpReply = (MultipartReplyMessage)msg;
58 NodeId node = this.nodeIdFromDatapathId(sc.getFeatures().getDatapathId());
59 switch (mpReply.getType()){
61 logger.info("Received group statistics multipart reponse");
62 GroupStatisticsUpdatedBuilder message = new GroupStatisticsUpdatedBuilder();
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;
73 logger.info("Received group description statistics multipart reponse");
75 GroupDescStatsUpdatedBuilder message = new GroupDescStatsUpdatedBuilder();
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;
85 case OFPMPGROUPFEATURES: {
86 logger.info("Received group features multipart reponse");
87 GroupFeaturesUpdatedBuilder message = new GroupFeaturesUpdatedBuilder();
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()));
102 message.setActions(getGroupActionsSupportBitmap(replyBody.getActionsBitmap()));
103 listDataObject.add(message.build());
104 return listDataObject;
107 logger.info("Received meter statistics multipart reponse");
108 MeterStatisticsUpdatedBuilder message = new MeterStatisticsUpdatedBuilder();
110 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
111 message.setTransactionId(generateTransactionId(mpReply.getXid()));
113 MultipartReplyMeter replyBody = (MultipartReplyMeter)mpReply.getMultipartReplyBody();
114 message.setMeterStats(meterStatsConvertor.toSALMeterStatsList(replyBody.getMeterStats()));
116 listDataObject.add(message.build());
117 return listDataObject;
119 case OFPMPMETERCONFIG:{
120 logger.info("Received meter config statistics multipart reponse");
122 MeterConfigStatsUpdatedBuilder message = new MeterConfigStatsUpdatedBuilder();
124 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
125 message.setTransactionId(generateTransactionId(mpReply.getXid()));
127 MultipartReplyMeterConfig replyBody = (MultipartReplyMeterConfig)mpReply.getMultipartReplyBody();
128 message.setMeterConfigStats(meterStatsConvertor.toSALMeterConfigList(replyBody.getMeterConfig()));
129 listDataObject.add(message.build());
130 return listDataObject;
132 case OFPMPMETERFEATURES:{
133 logger.info("Received meter features multipart reponse");
135 MeterFeaturesUpdatedBuilder message = new MeterFeaturesUpdatedBuilder();
137 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
138 message.setTransactionId(generateTransactionId(mpReply.getXid()));
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())));
146 // TODO: Band Types is bitmaps, but plugin is receiving enum.
148 //message.setBandTypes(replyBody.getBandTypes())
149 listDataObject.add(message.build());
150 return listDataObject;
153 logger.info(" Type : {}, not handled yet",mpReply.getType().name() );
154 return listDataObject;
158 return listDataObject;
161 private NodeId nodeIdFromDatapathId(BigInteger datapathId) {
162 String current = datapathId.toString();
163 return new NodeId("openflow:" + current);
166 private TransactionId generateTransactionId(Long xid){
167 String stringXid =xid.toString();
168 BigInteger bigIntXid = new BigInteger( stringXid );
169 return new TransactionId(bigIntXid);
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
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));
205 return supportActionByGroups;
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
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;