Floodlight 中创建消息对象的方法

  
     在 floodlight 中创建各种openflow message 和 action 等采用的是 简单工厂 方式,BasicFactory类(实现 OFMessageFactory接口, )会根据消息的类型创建不同的对象,达到更好的封装效果;此外这里调用的是枚举类型的方法。下面是具体代码:

----------工厂接口,还有OFActionFactory,约束需要具体工厂完成的事情
public   interface  OFMessageFactory {
       // 根据消息类型得到具体的实例
       public  OFMessage getMessage(OFType t);

       // 尝试从ChannelBuffer中解析出尽可能多的OFMessage,从position开始,止于一个解析的消息之后
       public  List <OFMessage> parseMessage(ChannelBuffer data)
                throws  MessageParseException;

       // 得到负责创建openflow action 的工厂
       public  OFActionFactory getActionFactory();
}

---------工厂类
    //创建  openflow  message和action
public   class  BasicFactory  implements  OFMessageFactory, OFActionFactory,
          OFStatisticsFactory, OFVendorDataFactory {
       @Override
       public  OFMessage getMessage(OFType t) {
            return t.newInstance(); // 调用枚举类型的方法
     }

       @Override
       public  List<OFMessage> parseMessage(ChannelBuffer data)
                throws  MessageParseException {
          List<OFMessage> msglist =  new  ArrayList<OFMessage>();
          OFMessage msg =  null  ;

            while  (data.readableBytes() >= OFMessage. MINIMUM_LENGTH  ) {
              data.markReaderIndex();  // 标记读指针,注意ChannelBuffer和ByteBuffer的区别
              msg =  this  .parseMessageOne(data);
                if  (msg ==  null  ) {
                   data.resetReaderIndex();  // 如果失败则恢复read index
                     break  ;
              }  else  {
                   msglist.add(msg);  // 成功解析,则将其加入列表
              }
          }

            if  (msglist.size() == 0) {
                return   null  ;
          }
            return  msglist;
     }

       public  OFMessage parseMessageOne(ChannelBuffer data)
                throws  MessageParseException {
            try  {
              OFMessage demux =  new  OFMessage();
              OFMessage ofm =  null  ;

                if  (data.readableBytes() < OFMessage. MINIMUM_LENGTH  )
                     return  ofm;

              data.markReaderIndex();
               // 调用基类方法,得到OF header的字段如长度和消息类型
              demux.readFrom(data);
              data.resetReaderIndex();

                // 如果ChannelBuffer中不足一个消息长度,则返回空
                if  (demux.getLengthU() > data.readableBytes())
                     return  ofm;
                // 否则根据类型,创建相应的消息对象
              ofm = getMessage(demux.getType());
                if  (ofm ==  null  )
                     return   null  ;
                // 如果相应的消息类中有OFActionFactory成员,就用当前类设置它
                if  (ofm  instanceof  OFActionFactoryAware) {
                   ((OFActionFactoryAware) ofm).setActionFactory( this  );
              }
                if  (ofm  instanceof  OFMessageFactoryAware) {
                   ((OFMessageFactoryAware) ofm).setMessageFactory( this  );
              }
                if  (ofm  instanceof  OFStatisticsFactoryAware) {
                   ((OFStatisticsFactoryAware) ofm).setStatisticsFactory( this  );
              }
                if  (ofm  instanceof  OFVendorDataFactoryAware) {
                   ((OFVendorDataFactoryAware) ofm).setVendorDataFactory( this  );
              }
                // 最后调用具体类的readFrom,从ChannelBuffer解析出该消息
              ofm.readFrom(data);
                if  (OFMessage.  class .equals(ofm.getClass())) {
                     // advance the position for un-implemented messages
                   data.readerIndex(data.readerIndex()
                             + (ofm.getLengthU() - OFMessage. MINIMUM_LENGTH  ));
              }

                return  ofm;
          }  catch  (Exception e) {
                throw   new  MessageParseException(e);
          }
     }

// 下面的action和statistics 与上面类似。 
          @Override
       public  OFAction getAction(OFActionType t) {
            return  t.newInstance();
     }

       @Override
       public  List<OFAction> parseActions(ChannelBuffer data,  int  length) {
            return  parseActions(data, length, 0);
     }

       @Override
       public  List<OFAction> parseActions(ChannelBuffer data,  int  length,  int  limit) {
          List<OFAction> results =  new  ArrayList<OFAction>();
          OFAction demux =  new  OFAction();
          OFAction ofa;
            int  end = data.readerIndex() + length;

            while  (limit == 0 || results.size() <= limit) {
                if  ((data.readableBytes() < OFAction. MINIMUM_LENGTH  || (data
                        .readerIndex() + OFAction. MINIMUM_LENGTH  ) > end))
                     return  results;

              data.markReaderIndex();
              demux.readFrom(data);
              data.resetReaderIndex();

                if  ((demux.getLengthU() > data.readableBytes() || (data
                        .readerIndex() + demux.getLengthU()) > end))
                     return  results;

              ofa = getAction(demux.getType());
              ofa.readFrom(data);
                if  (OFAction.  class .equals(ofa.getClass())) {
                     // advance the position for un-implemented messages
                   data.readerIndex(data.readerIndex()
                             + (ofa.getLengthU() - OFAction. MINIMUM_LENGTH  ));
              }
              results.add(ofa);
          }

            return  results;
     }

       
       @Override
       public  OFActionFactory getActionFactory() {
            return   this  ;
     }
}  
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值