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.controller.sal.binding.api.data.DataModificationTransaction;
9 import org.opendaylight.openflowplugin.openflow.md.core.IMDMessageTranslator;
10 import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
11 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.GroupStatsResponseConvertor;
12 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.MeterStatsResponseConvertor;
13 import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext;
14 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.Counter32;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdatedBuilder;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupFeaturesUpdatedBuilder;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdatedBuilder;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeatures;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeaturesBuilder;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.features.GroupFeaturesBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.Chaining;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.ChainingChecks;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupAll;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupCapability;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupFf;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupIndirect;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupSelect;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupType;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.SelectLiveness;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.SelectWeight;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterConfigStatsUpdatedBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterFeaturesUpdatedBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterStatisticsUpdatedBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeatures;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeaturesBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.MeterFeaturesBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBand;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandDrop;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandDscpRemark;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBurst;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterCapability;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterKbps;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterPktps;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterStats;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroup;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDesc;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupFeatures;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeter;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfig;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeatures;
57 import org.opendaylight.yangtools.yang.binding.DataObject;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
62 * Class converts multipart reply messages to the notification objects defined
63 * by statistics provider (manager ).
65 * @author avishnoi@in.ibm.com
68 public class MultipartReplyTranslator implements IMDMessageTranslator<OfHeader, List<DataObject>> {
70 protected static final Logger logger = LoggerFactory
71 .getLogger(MultipartReplyTranslator.class);
73 private static GroupStatsResponseConvertor groupStatsConvertor = new GroupStatsResponseConvertor();
74 private static MeterStatsResponseConvertor meterStatsConvertor = new MeterStatsResponseConvertor();
77 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sc, OfHeader msg) {
79 List<DataObject> listDataObject = new CopyOnWriteArrayList<DataObject>();
81 if(msg instanceof MultipartReplyMessage){
82 MultipartReplyMessage mpReply = (MultipartReplyMessage)msg;
83 NodeId node = this.nodeIdFromDatapathId(sc.getFeatures().getDatapathId());
84 switch (mpReply.getType()){
86 logger.info("Received group statistics multipart reponse");
87 GroupStatisticsUpdatedBuilder message = new GroupStatisticsUpdatedBuilder();
89 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
90 message.setTransactionId(generateTransactionId(mpReply.getXid()));
91 MultipartReplyGroup replyBody = (MultipartReplyGroup)mpReply.getMultipartReplyBody();
92 message.setGroupStats(groupStatsConvertor.toSALGroupStatsList(replyBody.getGroupStats()));
93 logger.debug("Converted group statistics : {}",message.toString());
94 listDataObject.add(message.build());
95 return listDataObject;
98 logger.info("Received group description statistics multipart reponse");
100 GroupDescStatsUpdatedBuilder message = new GroupDescStatsUpdatedBuilder();
102 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
103 message.setTransactionId(generateTransactionId(mpReply.getXid()));
104 MultipartReplyGroupDesc replyBody = (MultipartReplyGroupDesc)mpReply.getMultipartReplyBody();
105 message.setGroupDescStats(groupStatsConvertor.toSALGroupDescStatsList(replyBody.getGroupDesc()));
106 logger.debug("Converted group statistics : {}",message.toString());
107 listDataObject.add(message.build());
108 return listDataObject;
110 case OFPMPGROUPFEATURES: {
111 logger.info("Received group features multipart reponse");
112 GroupFeaturesUpdatedBuilder message = new GroupFeaturesUpdatedBuilder();
114 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
115 message.setTransactionId(generateTransactionId(mpReply.getXid()));
116 MultipartReplyGroupFeatures replyBody = (MultipartReplyGroupFeatures)mpReply.getMultipartReplyBody();
117 List<Class<? extends GroupType>> supportedGroups =
118 new ArrayList<Class<? extends GroupType>>();
120 if(replyBody.getTypes().isOFPGTALL()){
121 supportedGroups.add(GroupAll.class);
123 if(replyBody.getTypes().isOFPGTSELECT()){
124 supportedGroups.add(GroupSelect.class);
126 if(replyBody.getTypes().isOFPGTINDIRECT()){
127 supportedGroups.add(GroupIndirect.class);
129 if(replyBody.getTypes().isOFPGTFF()){
130 supportedGroups.add(GroupFf.class);
132 message.setGroupTypesSupported(supportedGroups);
133 message.setMaxGroups(replyBody.getMaxGroups());
135 List<Class<? extends GroupCapability>> supportedCapabilities =
136 new ArrayList<Class<? extends GroupCapability>>();
138 if(replyBody.getCapabilities().isOFPGFCCHAINING()){
139 supportedCapabilities.add(Chaining.class);
141 if(replyBody.getCapabilities().isOFPGFCCHAININGCHECKS()){
142 supportedCapabilities.add(ChainingChecks.class);
144 if(replyBody.getCapabilities().isOFPGFCSELECTLIVENESS()){
145 supportedCapabilities.add(SelectLiveness.class);
147 if(replyBody.getCapabilities().isOFPGFCSELECTWEIGHT()){
148 supportedCapabilities.add(SelectWeight.class);
151 message.setGroupCapabilitiesSupported(supportedCapabilities);
153 message.setActions(getGroupActionsSupportBitmap(replyBody.getActionsBitmap()));
154 listDataObject.add(message.build());
156 //augmentGroupFeaturesToNode(message);
158 //Send update notification to all the listeners
159 return listDataObject;
162 logger.info("Received meter statistics multipart reponse");
163 MeterStatisticsUpdatedBuilder message = new MeterStatisticsUpdatedBuilder();
165 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
166 message.setTransactionId(generateTransactionId(mpReply.getXid()));
168 MultipartReplyMeter replyBody = (MultipartReplyMeter)mpReply.getMultipartReplyBody();
169 message.setMeterStats(meterStatsConvertor.toSALMeterStatsList(replyBody.getMeterStats()));
171 listDataObject.add(message.build());
172 return listDataObject;
174 case OFPMPMETERCONFIG:{
175 logger.info("Received meter config statistics multipart reponse");
177 MeterConfigStatsUpdatedBuilder message = new MeterConfigStatsUpdatedBuilder();
179 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
180 message.setTransactionId(generateTransactionId(mpReply.getXid()));
182 MultipartReplyMeterConfig replyBody = (MultipartReplyMeterConfig)mpReply.getMultipartReplyBody();
183 message.setMeterConfigStats(meterStatsConvertor.toSALMeterConfigList(replyBody.getMeterConfig()));
184 listDataObject.add(message.build());
185 return listDataObject;
187 case OFPMPMETERFEATURES:{
188 logger.info("Received meter features multipart reponse");
189 //Convert OF message and send it to SAL listener
190 MeterFeaturesUpdatedBuilder message = new MeterFeaturesUpdatedBuilder();
192 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
193 message.setTransactionId(generateTransactionId(mpReply.getXid()));
195 MultipartReplyMeterFeatures replyBody = (MultipartReplyMeterFeatures)mpReply.getMultipartReplyBody();
196 message.setMaxBands(replyBody.getMaxBands());
197 message.setMaxColor(replyBody.getMaxColor());
198 message.setMaxMeter(new Counter32(replyBody.getMaxMeter()));
200 List<Class<? extends MeterCapability>> supportedCapabilities =
201 new ArrayList<Class<? extends MeterCapability>>();
202 if(replyBody.getCapabilities().isOFPMFBURST()){
203 supportedCapabilities.add(MeterBurst.class);
205 if(replyBody.getCapabilities().isOFPMFKBPS()){
206 supportedCapabilities.add(MeterKbps.class);
209 if(replyBody.getCapabilities().isOFPMFPKTPS()){
210 supportedCapabilities.add(MeterPktps.class);
213 if(replyBody.getCapabilities().isOFPMFSTATS()){
214 supportedCapabilities.add(MeterStats.class);
217 message.setMeterCapabilitiesSupported(supportedCapabilities);
219 List<Class<? extends MeterBand>> supportedMeterBand =
220 new ArrayList<Class <? extends MeterBand>>();
221 if(replyBody.getBandTypes().isOFPMBTDROP()){
222 supportedMeterBand.add(MeterBandDrop.class);
224 if(replyBody.getBandTypes().isOFPMBTDSCPREMARK()){
225 supportedMeterBand.add(MeterBandDscpRemark.class);
227 message.setMeterBandSupported(supportedMeterBand);
228 listDataObject.add(message.build());
230 //augmentMeterFeaturesToNode(message);
232 //Send update notification to all the listeners
233 return listDataObject;
236 logger.info(" Type : {}, not handled yet",mpReply.getType().name() );
237 return listDataObject;
241 return listDataObject;
244 private void augmentGroupFeaturesToNode(GroupFeaturesUpdatedBuilder message){
245 GroupFeaturesBuilder groupFeatures = new GroupFeaturesBuilder();
246 groupFeatures.setActions(message.getActions());
247 groupFeatures.setGroupCapabilitiesSupported(message.getGroupCapabilitiesSupported());
248 groupFeatures.setGroupTypesSupported(message.getGroupTypesSupported());
249 groupFeatures.setMaxGroups(message.getMaxGroups());
251 final NodeBuilder nodeData = new NodeBuilder();
252 nodeData.setKey(new NodeKey(message.getId()));
254 NodeGroupFeaturesBuilder nodeGroupFeatures= new NodeGroupFeaturesBuilder();
255 nodeGroupFeatures.setGroupFeatures(groupFeatures.build());
256 //Update augmented data
257 nodeData.addAugmentation(NodeGroupFeatures.class, nodeGroupFeatures.build());
260 private void augmentMeterFeaturesToNode(MeterFeaturesUpdatedBuilder message){
261 MeterFeaturesBuilder meterFeature = new MeterFeaturesBuilder();
262 meterFeature.setMeterBandSupported(message.getMeterBandSupported());
263 meterFeature.setMeterCapabilitiesSupported(message.getMeterCapabilitiesSupported());
264 meterFeature.setMaxBands(message.getMaxBands());
265 meterFeature.setMaxColor(message.getMaxColor());
266 meterFeature.setMaxMeter(message.getMaxMeter());
268 final NodeBuilder nodeData = new NodeBuilder();
269 nodeData.setKey(new NodeKey(message.getId()));
271 NodeMeterFeaturesBuilder nodeMeterFeatures= new NodeMeterFeaturesBuilder();
272 nodeMeterFeatures.setMeterFeatures(meterFeature.build());
273 //Update augmented data
274 nodeData.addAugmentation(NodeMeterFeatures.class, nodeMeterFeatures.build());
277 private NodeId nodeIdFromDatapathId(BigInteger datapathId) {
278 String current = datapathId.toString();
279 return new NodeId("openflow:" + current);
282 private TransactionId generateTransactionId(Long xid){
283 String stringXid =xid.toString();
284 BigInteger bigIntXid = new BigInteger( stringXid );
285 return new TransactionId(bigIntXid);
290 * Method returns the bitmap of actions supported by each group.
291 * TODO: My recommendation would be, its good to have a respective model of
292 * 'type bits', which will generate a class where all these flags will eventually
293 * be stored as boolean. It will be convenient for application to check the
294 * supported action, rather then doing bitmap operation.
295 * @param actionsSupported
298 private List<Long> getGroupActionsSupportBitmap(List<org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionType> actionsSupported){
299 List<Long> supportActionByGroups = new ArrayList<Long>();
300 for(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionType supportedActions : actionsSupported){
301 long supportActionBitmap = 0;
302 supportActionBitmap |= supportedActions.isOFPATOUTPUT()?(1 << 0): ~(1 << 0);
303 supportActionBitmap |= supportedActions.isOFPATCOPYTTLOUT()?(1 << 11): ~(1 << 11);
304 supportActionBitmap |= supportedActions.isOFPATCOPYTTLIN()?(1 << 12): ~(1 << 12);
305 supportActionBitmap |= supportedActions.isOFPATSETMPLSTTL()?(1 << 15): ~(1 << 15);
306 supportActionBitmap |= supportedActions.isOFPATDECMPLSTTL()?(1 << 16): ~(1 << 16);
307 supportActionBitmap |= supportedActions.isOFPATPUSHVLAN()?(1 << 16): ~(1 << 16);
308 supportActionBitmap |= supportedActions.isOFPATPOPVLAN()?(1 << 17): ~(1 << 17);
309 supportActionBitmap |= supportedActions.isOFPATPUSHMPLS()?(1 << 18): ~(1 << 18);
310 supportActionBitmap |= supportedActions.isOFPATPOPMPLS()?(1 << 19): ~(1 << 19);
311 supportActionBitmap |= supportedActions.isOFPATSETQUEUE()?(1 << 20): ~(1 << 20);
312 supportActionBitmap |= supportedActions.isOFPATGROUP()?(1 << 21): ~(1 << 21);
313 supportActionBitmap |= supportedActions.isOFPATSETNWTTL()?(1 << 22): ~(1 << 22);
314 supportActionBitmap |= supportedActions.isOFPATDECNWTTL()?(1 << 23): ~(1 << 23);
315 supportActionBitmap |= supportedActions.isOFPATSETFIELD()?(1 << 24): ~(1 << 24);
316 supportActionBitmap |= supportedActions.isOFPATPUSHPBB()?(1 << 25): ~(1 << 25);
317 supportActionBitmap |= supportedActions.isOFPATPOPPBB()?(1 << 26): ~(1 << 26);
318 supportActionBitmap |= supportedActions.isOFPATEXPERIMENTER()?(1 << 27): ~(1 << 27);
319 supportActionByGroups.add(new Long(supportActionBitmap));
321 return supportActionByGroups;