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.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;
53 * Class converts multipart reply messages to the notification objects defined
54 * by statistics provider (manager ).
56 * @author avishnoi@in.ibm.com
59 public class MultipartReplyTranslator implements IMDMessageTranslator<OfHeader, List<DataObject>> {
61 protected static final Logger logger = LoggerFactory
62 .getLogger(MultipartReplyTranslator.class);
64 private static GroupStatsResponseConvertor groupStatsConvertor = new GroupStatsResponseConvertor();
65 private static MeterStatsResponseConvertor meterStatsConvertor = new MeterStatsResponseConvertor();
68 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sc, OfHeader msg) {
70 List<DataObject> listDataObject = new CopyOnWriteArrayList<DataObject>();
72 if(msg instanceof MultipartReplyMessage){
73 MultipartReplyMessage mpReply = (MultipartReplyMessage)msg;
74 NodeId node = this.nodeIdFromDatapathId(sc.getFeatures().getDatapathId());
75 switch (mpReply.getType()){
77 logger.info("Received group statistics multipart reponse");
78 GroupStatisticsUpdatedBuilder message = new GroupStatisticsUpdatedBuilder();
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;
89 logger.info("Received group description statistics multipart reponse");
91 GroupDescStatsUpdatedBuilder message = new GroupDescStatsUpdatedBuilder();
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;
101 case OFPMPGROUPFEATURES: {
102 logger.info("Received group features multipart reponse");
103 GroupFeaturesUpdatedBuilder message = new GroupFeaturesUpdatedBuilder();
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>>();
111 if(replyBody.getTypes().isOFPGTALL()){
112 supportedGroups.add(GroupAll.class);
114 if(replyBody.getTypes().isOFPGTSELECT()){
115 supportedGroups.add(GroupSelect.class);
117 if(replyBody.getTypes().isOFPGTINDIRECT()){
118 supportedGroups.add(GroupIndirect.class);
120 if(replyBody.getTypes().isOFPGTFF()){
121 supportedGroups.add(GroupFf.class);
123 message.setGroupTypesSupported(supportedGroups);
124 message.setMaxGroups(replyBody.getMaxGroups());
126 List<Class<? extends GroupCapability>> supportedCapabilities =
127 new ArrayList<Class<? extends GroupCapability>>();
129 if(replyBody.getCapabilities().isOFPGFCCHAINING()){
130 supportedCapabilities.add(Chaining.class);
132 if(replyBody.getCapabilities().isOFPGFCCHAININGCHECKS()){
133 supportedCapabilities.add(ChainingChecks.class);
135 if(replyBody.getCapabilities().isOFPGFCSELECTLIVENESS()){
136 supportedCapabilities.add(SelectLiveness.class);
138 if(replyBody.getCapabilities().isOFPGFCSELECTWEIGHT()){
139 supportedCapabilities.add(SelectWeight.class);
142 message.setGroupCapabilitiesSupported(supportedCapabilities);
144 message.setActions(getGroupActionsSupportBitmap(replyBody.getActionsBitmap()));
145 listDataObject.add(message.build());
147 //augmentGroupFeaturesToNode(message);
149 //Send update notification to all the listeners
150 return listDataObject;
153 logger.info("Received meter statistics multipart reponse");
154 MeterStatisticsUpdatedBuilder message = new MeterStatisticsUpdatedBuilder();
156 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
157 message.setTransactionId(generateTransactionId(mpReply.getXid()));
159 MultipartReplyMeter replyBody = (MultipartReplyMeter)mpReply.getMultipartReplyBody();
160 message.setMeterStats(meterStatsConvertor.toSALMeterStatsList(replyBody.getMeterStats()));
162 listDataObject.add(message.build());
163 return listDataObject;
165 case OFPMPMETERCONFIG:{
166 logger.info("Received meter config statistics multipart reponse");
168 MeterConfigStatsUpdatedBuilder message = new MeterConfigStatsUpdatedBuilder();
170 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
171 message.setTransactionId(generateTransactionId(mpReply.getXid()));
173 MultipartReplyMeterConfig replyBody = (MultipartReplyMeterConfig)mpReply.getMultipartReplyBody();
174 message.setMeterConfigStats(meterStatsConvertor.toSALMeterConfigList(replyBody.getMeterConfig()));
175 listDataObject.add(message.build());
176 return listDataObject;
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();
183 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
184 message.setTransactionId(generateTransactionId(mpReply.getXid()));
186 MultipartReplyMeterFeatures replyBody = (MultipartReplyMeterFeatures)mpReply.getMultipartReplyBody();
187 message.setMaxBands(replyBody.getMaxBands());
188 message.setMaxColor(replyBody.getMaxColor());
189 message.setMaxMeter(new Counter32(replyBody.getMaxMeter()));
191 List<Class<? extends MeterCapability>> supportedCapabilities =
192 new ArrayList<Class<? extends MeterCapability>>();
193 if(replyBody.getCapabilities().isOFPMFBURST()){
194 supportedCapabilities.add(MeterBurst.class);
196 if(replyBody.getCapabilities().isOFPMFKBPS()){
197 supportedCapabilities.add(MeterKbps.class);
200 if(replyBody.getCapabilities().isOFPMFPKTPS()){
201 supportedCapabilities.add(MeterPktps.class);
204 if(replyBody.getCapabilities().isOFPMFSTATS()){
205 supportedCapabilities.add(MeterStats.class);
208 message.setMeterCapabilitiesSupported(supportedCapabilities);
210 List<Class<? extends MeterBand>> supportedMeterBand =
211 new ArrayList<Class <? extends MeterBand>>();
212 if(replyBody.getBandTypes().isOFPMBTDROP()){
213 supportedMeterBand.add(MeterBandDrop.class);
215 if(replyBody.getBandTypes().isOFPMBTDSCPREMARK()){
216 supportedMeterBand.add(MeterBandDscpRemark.class);
218 message.setMeterBandSupported(supportedMeterBand);
219 listDataObject.add(message.build());
221 //augmentMeterFeaturesToNode(message);
223 //Send update notification to all the listeners
224 return listDataObject;
227 logger.info(" Type : {}, not handled yet",mpReply.getType().name() );
228 return listDataObject;
232 return listDataObject;
235 private NodeId nodeIdFromDatapathId(BigInteger datapathId) {
236 String current = datapathId.toString();
237 return new NodeId("openflow:" + current);
240 private TransactionId generateTransactionId(Long xid){
241 String stringXid =xid.toString();
242 BigInteger bigIntXid = new BigInteger( stringXid );
243 return new TransactionId(bigIntXid);
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
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));
279 return supportActionByGroups;