Floodlight 中创建消息对象的方法

Posted mfmdaoyou

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 ;
     }
}  

以上是关于Floodlight 中创建消息对象的方法的主要内容,如果未能解决你的问题,请参考以下文章

Android---Handler消息处理机制

在java中创建内部类对象的问题

android handle详解2 主线程给子线程发送消息

Java中创建对象的5种方法

通过其他类构造函数在主方法中创建对象时访问对象属性

Floodlight下发流表过程分析