在 floodlight 中创建各种openflow message 和 action 等採用的是简单工厂方式。BasicFactory类(实现OFMessageFactory接口。)会依据消息的类型创建不同的对象,达到更好的封装效果。此外这里调用的是枚举类型的方法。以下是详细代码:
----------工厂接口,还有OFActionFactory。约束须要详细工厂完毕的事情
public interface OFMessageFactory
{
{
// 依据消息类型得到详细的实例
public OFMessage
getMessage(OFType t);
getMessage(OFType t);
// 尝试从ChannelBuffer中解析出尽可能多的OFMessage,从position開始,止于一个解析的消息之后
public List <OFMessage>
parseMessage(ChannelBuffer data)
parseMessage(ChannelBuffer data)
throws MessageParseException;
// 得到负责创建openflow action
的工厂
的工厂
public OFActionFactory
getActionFactory();
getActionFactory();
}
---------工厂类
//创建 openflow message和action
public class BasicFactory implements OFMessageFactory,
OFActionFactory,
OFActionFactory,
OFStatisticsFactory, OFVendorDataFactory {
@Override
public OFMessage
getMessage(OFType t) {
getMessage(OFType t) {
return t.newInstance(); //
调用枚举类型的方法
调用枚举类型的方法
}
@Override
public List<OFMessage>
parseMessage(ChannelBuffer data)
parseMessage(ChannelBuffer data)
throws MessageParseException
{
{
List<OFMessage> msglist = new ArrayList<OFMessage>();
OFMessage msg = null ;
while (data.readableBytes()
>= OFMessage.MINIMUM_LENGTH ) {
>= OFMessage.MINIMUM_LENGTH ) {
data.markReaderIndex(); //
标记读指针,注意ChannelBuffer和ByteBuffer的差别
标记读指针,注意ChannelBuffer和ByteBuffer的差别
msg = this .parseMessageOne(data);
if (msg
== null ) {
== null ) {
data.resetReaderIndex(); //
假设失败则恢复read index
假设失败则恢复read index
break ;
} else {
msglist.add(msg); //
成功解析。则将其增加列表
成功解析。则将其增加列表
}
}
if (msglist.size()
== 0) {
== 0) {
return null ;
}
return msglist;
}
public OFMessage
parseMessageOne(ChannelBuffer data)
parseMessageOne(ChannelBuffer data)
throws MessageParseException
{
{
try {
OFMessage demux = new OFMessage();
OFMessage ofm = null ;
if (data.readableBytes()
< OFMessage.MINIMUM_LENGTH )
< OFMessage.MINIMUM_LENGTH )
return ofm;
data.markReaderIndex();
//
调用基类方法,得到OF header的字段如长度和消息类型
调用基类方法,得到OF header的字段如长度和消息类型
demux.readFrom(data);
data.resetReaderIndex();
//
假设ChannelBuffer中不足一个消息长度,则返回空
假设ChannelBuffer中不足一个消息长度,则返回空
if (demux.getLengthU()
> data.readableBytes())
> data.readableBytes())
return ofm;
//
否则依据类型。创建对应的消息对象
否则依据类型。创建对应的消息对象
ofm = getMessage(demux.getType());
if (ofm
== null )
== null )
return null ;
//
假设对应的消息类中有OFActionFactory成员,就用当前类设置它
假设对应的消息类中有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解析出该消息
最后调用详细类的readFrom。从ChannelBuffer解析出该消息
ofm.readFrom(data);
if (OFMessage. class.equals(ofm.getClass()))
{
{
//
advance the position for un-implemented messages
advance the position for un-implemented messages
data.readerIndex(data.readerIndex()
+ (ofm.getLengthU() - OFMessage.MINIMUM_LENGTH ));
}
return ofm;
} catch (Exception
e) {
e) {
throw new MessageParseException(e);
}
}
// 以下的action和statistics 与上面类似。
@Override
public OFAction
getAction(OFActionType t) {
getAction(OFActionType t) {
return t.newInstance();
}
@Override
public List<OFAction>
parseActions(ChannelBuffer data, int length)
{
parseActions(ChannelBuffer data, int length)
{
return parseActions(data,
length, 0);
length, 0);
}
@Override
public List<OFAction>
parseActions(ChannelBuffer data, int length, int limit)
{
parseActions(ChannelBuffer data, int length, int limit)
{
List<OFAction> results = new ArrayList<OFAction>();
OFAction demux = new OFAction();
OFAction ofa;
int end
= data.readerIndex() + length;
= data.readerIndex() + length;
while (limit
== 0 || results.size() <= limit) {
== 0 || results.size() <= limit) {
if ((data.readableBytes()
< OFAction.MINIMUM_LENGTH || (data
< OFAction.MINIMUM_LENGTH || (data
.readerIndex() + OFAction.MINIMUM_LENGTH )
> end))
> end))
return results;
data.markReaderIndex();
demux.readFrom(data);
data.resetReaderIndex();
if ((demux.getLengthU()
> data.readableBytes() || (data
> 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
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() {
getActionFactory() {
return this ;
}
}