• 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 ;
         }
    }  
  • 相关阅读:
    Android 课程设计
    第十个作业 简易通讯录
    第九个作业 QQ的账号密码保存
    第八个作业 QQ账号的保存
    第七个作业 Activity之间的数据回传
    第六个作业 应用列表
    第五个作业 背景换色
    JSP第一次作业
    安卓课设
    Android第八次作业
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/6901974.html
Copyright © 2020-2023  润新知