在 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
;
}
}