floodlight添加模塊實驗

導入工程:

Git上直接拉下來的代碼是沒法直接導入到eclipse中的,需要添加.project文件和,classpath文件:

Project文件:

[html] view plain copy
 print?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.     <projectDescription>  
  3.         <name>floodlight</name>  
  4.         <comment></comment>  
  5.         <projects>  
  6.         </projects>  
  7.         <buildSpec>  
  8.             <buildCommand>  
  9.                 <name>org.python.pydev.PyDevBuilder</name>  
  10.                 <arguments>  
  11.                 </arguments>  
  12.             </buildCommand>  
  13.             <buildCommand>  
  14.                 <name>org.eclipse.jdt.core.javabuilder</name>  
  15.                 <arguments>  
  16.                 </arguments>  
  17.              </buildCommand>  
  18.         </buildSpec>  
  19.         <natures>  
  20.             <nature>org.eclipse.jdt.core.javanature</nature>  
  21.             <nature>org.python.pydev.pythonNature</nature>  
  22.         </natures>  
  23. </projectDescription>  


Classpath文件:

[html] view plain copy
 print?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <classpath>  
  3.     <classpathentry kind="src" output="target/bin" path="src/main/java"/>  
  4.     <classpathentry kind="src" path="src/main/resources"/>  
  5.     <classpathentry kind="src" output="target/bin-test" path="src/test/java"/>  
  6.     <classpathentry kind="src" path="src/test/resources"/>  
  7.     <classpathentry kind="src" output="target/bin" path="lib/gen-java"/>  
  8.     <classpathentry exported="true" kind="lib" path="lib/args4j-2.0.16.jar"/>  
  9.     <classpathentry exported="true" kind="lib" path="lib/cglib-nodep-2.2.2.jar"/>  
  10.     <classpathentry exported="true" kind="lib" path="lib/concurrentlinkedhashmap-lru-1.2.jar"/>  
  11.     <classpathentry exported="true" kind="lib" path="lib/derby-10.9.1.0.jar"/>  
  12.     <classpathentry exported="true" kind="lib" path="lib/findbugs-annotations-2.0.1.jar"/>  
  13.     <classpathentry exported="true" kind="lib" path="lib/findbugs-jsr305-2.0.1.jar"/>  
  14.     <classpathentry exported="true" kind="lib" path="lib/guava-13.0.1.jar"/>  
  15.     <classpathentry exported="true" kind="lib" path="lib/jackson-annotations-2.1.4.jar"/>  
  16.     <classpathentry exported="true" kind="lib" path="lib/jackson-core-2.1.4.jar"/>  
  17.     <classpathentry exported="true" kind="lib" path="lib/jackson-databind-2.1.4.jar"/>  
  18.     <classpathentry exported="true" kind="lib" path="lib/jackson-dataformat-csv-2.1.4.jar"/>  
  19.     <classpathentry exported="true" kind="lib" path="lib/jackson-dataformat-smile-2.1.4.jar"/>  
  20.     <classpathentry exported="true" kind="lib" path="lib/jackson-dataformat-xml-2.1.4.jar"/>  
  21.     <classpathentry exported="true" kind="lib" path="lib/jackson-dataformat-yaml-2.1.4.jar"/>  
  22.     <classpathentry exported="true" kind="lib" path="lib/junit-4.8.2.jar" sourcepath="C:/Users/dell/.m2/repository/junit/junit/4.8.2/junit-4.8.2-sources.jar"/>  
  23.     <classpathentry exported="true" kind="lib" path="lib/jython-2.5.2.jar"/>  
  24.     <classpathentry exported="true" kind="lib" path="lib/libthrift-0.9.0.jar"/>  
  25.     <classpathentry exported="true" kind="lib" path="lib/logback-classic-1.0.0.jar"/>  
  26.     <classpathentry exported="true" kind="lib" path="lib/logback-core-1.0.0.jar"/>  
  27.     <classpathentry exported="true" kind="lib" path="lib/netty-3.2.6.Final.jar" sourcepath="C:/Users/dell/.m2/repository/org/jboss/netty/netty/3.2.6.Final/netty-3.2.6.Final-sources.jar"/>  
  28.     <classpathentry exported="true" kind="lib" path="lib/objenesis-1.2.jar"/>  
  29.     <classpathentry exported="true" kind="lib" path="lib/org.easymock-3.1.jar"/>  
  30.     <classpathentry exported="true" kind="lib" path="lib/org.restlet-2.2M3.jar"/>  
  31.     <classpathentry exported="true" kind="lib" path="lib/org.restlet.ext.jackson-2.2M3.jar"/>  
  32.     <classpathentry exported="true" kind="lib" path="lib/org.restlet.ext.simple-2.2M3.jar"/>  
  33.     <classpathentry exported="true" kind="lib" path="lib/org.restlet.ext.slf4j-2.2M3.jar"/>  
  34.     <classpathentry exported="true" kind="lib" path="lib/simple-5.1.1.jar"/>  
  35.     <classpathentry exported="true" kind="lib" path="lib/slf4j-api-1.6.4.jar"/>  
  36.     <classpathentry kind="lib" path="lib/asm-3.0.jar"/>  
  37.     <classpathentry kind="lib" path="lib/asm-tree-3.0.jar"/>  
  38.     <classpathentry kind="lib" path="lib/cobertura-1.9.4.1.jar"/>  
  39.     <classpathentry kind="lib" path="lib/hamcrest-core-1.3.jar"/>  
  40.     <classpathentry kind="lib" path="lib/hamcrest-integration-1.3.jar"/>  
  41.     <classpathentry kind="lib" path="lib/hamcrest-library-1.3.jar"/>  
  42.     <classpathentry kind="lib" path="lib/j3dutils.jar"/>  
  43.     <classpathentry kind="lib" path="lib/jdeb-1.0.1.jar"/>  
  44.     <classpathentry kind="lib" path="lib/log4j-1.2.9.jar"/>  
  45.     <classpathentry kind="lib" path="lib/openflowj-0.9.0-SNAPSHOT-javadoc.jar"/>  
  46.     <classpathentry kind="lib" path="lib/openflowj-0.9.0-SNAPSHOT-sources.jar"/>  
  47.     <classpathentry kind="lib" path="lib/openflowj-0.9.0-SNAPSHOT.jar"/>  
  48.     <classpathentry kind="lib" path="lib/packetstreamer-thrift.jar"/>  
  49.     <classpathentry kind="lib" path="lib/oro/jakarta-oro-2.0.8.jar"/>  
  50.     <classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>  
  51.     <classpathentry kind="output" path="target/bin"/>  
  52. </classpath>  

然後就可以作爲普通的項目導入即可。

實驗過程:

這裏的實驗做的是對packet-in包的數量進行統計並打印到控制檯,功能單一,但能體現出添加新模塊的整個流程。

 

1.添加新服務接口

首先需要定義新加模塊服務的接口:

[html] view plain copy
 print?
  1. package net.floodlightcontroller.statics;  
  2.   
  3. import net.floodlightcontroller.core.module.IFloodlightService;  
  4.   
  5. /**  
  6.  * The service registry  
  7.  * @author yangshuai  
  8.  */  
  9.   
  10. public interface IPktinHistoryService extends IFloodlightService {  
  11.     /*  
  12.      * 用於統計結果  
  13.      */  
  14.     public long getPackINCount();  
  15. }  



2.添加PktinHistory模塊:因爲這裏添加的新模塊的功能比較單一,只是統計floodlight運行後packet-in包的總數量,並且是持續累計計數的,所以只需在該接口中定義一個用於計算的方法就可以了。

定義PktinHistory模塊:

[html] view plain copy
 print?
  1. package net.floodlightcontroller.statics;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Collection;  
  5. import java.util.HashMap;  
  6. import java.util.Map;  
  7. import java.util.concurrent.atomic.AtomicLong;  
  8.   
  9. import org.projectfloodlight.openflow.protocol.OFMessage;  
  10. import org.projectfloodlight.openflow.protocol.OFType;  
  11. import org.slf4j.Logger;  
  12. import org.slf4j.LoggerFactory;  
  13.   
  14. import net.floodlightcontroller.core.FloodlightContext;  
  15. import net.floodlightcontroller.core.IFloodlightProviderService;  
  16. import net.floodlightcontroller.core.IOFMessageListener;  
  17. import net.floodlightcontroller.core.IOFSwitch;  
  18. import net.floodlightcontroller.core.module.FloodlightModuleContext;  
  19. import net.floodlightcontroller.core.module.FloodlightModuleException;  
  20. import net.floodlightcontroller.core.module.IFloodlightModule;  
  21. import net.floodlightcontroller.core.module.IFloodlightService;  
  22. import net.floodlightcontroller.restserver.IRestApiService;  
  23.   
  24. /*  
  25.  *   
  26.  *@author yangshuai  
  27.  */   
  28.   
  29. public class PktinHistory implements   
  30.     IOFMessageListener,IFloodlightModule,IPktinHistoryService{  
  31.   
  32.     protected static Logger log = LoggerFactory.getLogger(PktinHistory.class);  
  33.     protected IFloodlightProviderService FloodlightProvider ;  
  34.     protected IRestApiService restApi ;  
  35.     private AtomicLong PACKET_IN_COUNT = new AtomicLong() ;  
  36.       
  37.     @Override  
  38.     public String getName() {  
  39.         return "PktinHistory" ;  
  40.     }  
  41.   
  42.     @Override  
  43.     public boolean isCallbackOrderingPrereq(OFType type, String name) {  
  44.         // TODO Auto-generated method stub  
  45.         return false;  
  46.     }  
  47.   
  48.     @Override  
  49.     public boolean isCallbackOrderingPostreq(OFType type, String name) {  
  50.         // TODO Auto-generated method stub  
  51.         return false;  
  52.     }  
  53.   
  54.     @Override  
  55.     public long getPackINCount() {  
  56.         return PACKET_IN_COUNT.get();  
  57.     }  
  58.   
  59.     @Override  
  60.     public Collection<Class<? extends IFloodlightService>> getModuleServices() {  
  61.         Collection<Class<? extends IFloodlightService>> l =   
  62.                 new ArrayList<Class<? extends IFloodlightService>>();  
  63.         l.add(IPktinHistoryService.class);  
  64.         return l;  
  65.     }  
  66.   
  67.     @Override  
  68.     public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {  
  69.         Map<Class<? extends IFloodlightService>,IFloodlightService> m =   
  70.                 new  HashMap<Class<? extends IFloodlightService>,IFloodlightService>();  
  71.         m.put(IPktinHistoryService.class,this);  
  72.         return m;  
  73.     }  
  74.   
  75.     @Override  
  76.     public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {  
  77.         Collection<Class<? extends IFloodlightService>> l =   
  78.                 new ArrayList<Class<? extends IFloodlightService>>() ;  
  79.         l.add(IFloodlightProviderService.class);  
  80.         l.add(IRestApiService.class);  
  81.         return l ;  
  82.     }  
  83.   
  84.     @Override  
  85.     public void init(FloodlightModuleContext context)  
  86.             throws FloodlightModuleException {  
  87.         FloodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);  
  88.         restApi = context.getServiceImpl(IRestApiService.class) ;  
  89.     }  
  90.   
  91.     @Override  
  92.     public void startUp(FloodlightModuleContext context)  
  93.             throws FloodlightModuleException {  
  94.         FloodlightProvider.addOFMessageListener(OFType.PACKET_IN,this) ;  
  95.     }  
  96.   
  97.     @Override  
  98.     public net.floodlightcontroller.core.IListener.Command receive(  
  99.             IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {  
  100.         long count = PACKET_IN_COUNT.incrementAndGet() ;  
  101.         log.info("The total count of packet-in Messages are" + count);  
  102.         return Command.CONTINUE ;  
  103.     }  
  104.   
  105. }  

floodlight中所有的模塊都必須實現IFloodlightModule接口,而這裏新添加的模塊需要監聽數據包,所以也需要實現IOFMessageListener接口。IOFMessageListener接口用於監聽Packet-in消息,並記錄消息遞增數量,IPktinHistoryService接口是業務查詢接口,提供Packet-in數據分組統計結果查詢服務,IFloodLightModule接口標識該類是一個floodlight模塊,繼承該接口的類會在floodlight啓動過程中以模塊形式加載。該類文件可以隨意添加到任何包中,爲了方便管理和演示,這裏將所有添加該模塊所新建的文件全都放在了新建包net.floodlightcontroller.statics中。這個路勁在後面修改配置文件中仍然會使用到。

 

3.rest資源定義

在完成模塊的定義之後,需要對rest服務資源進行定義,這裏將類名定義爲:PktInHistoryResource,繼承抽象類ServerResourceServerResourceJava輕量級REST框架Restlet的抽象類),並實現業務邏輯。該步主要功能是將Packet-in統計接口包裝爲REST資源便於後續資源綁定。

[html] view plain copy
 print?
  1. package net.floodlightcontroller.statics;  
  2.   
  3. import java.util.HashMap;  
  4. import org.restlet.resource.Get;  
  5. import org.restlet.resource.ServerResource;  
  6.   
  7. /*  
  8.  *   
  9.  *@author yangshuai  
  10.  */   
  11.   
  12. public class PktInHistoryResource extends ServerResource{  
  13.     @Get("json")  
  14.       
  15.     public HashMap<String, String> retrieve(){  
  16.         IPktinHistoryService pihr = (IPktinHistoryService) getContext()  
  17.                 .getAttributes().get(IPktinHistoryService.class.getCanonicalName());  
  18.         long count = pihr.getPackINCount();  
  19.         HashMap<String, String> resp = new HashMap<String, String>() ;  
  20.         resp.put("Total", Long.toString(count)) ;  
  21.         return resp;  
  22.     }  
  23. }  

4.綁定urlrest資源

接着定義PktInHistoryWebRoutable類,將上步定義的PktInHistoryResource資源與訪問路徑綁定。該類中定義的路徑包括外部獲取該REST資源的基本路徑和相對路徑

[html] view plain copy
 print?
  1. package net.floodlightcontroller.statics;  
  2.   
  3. import net.floodlightcontroller.restserver.RestletRoutable;  
  4.   
  5. import org.restlet.Context;  
  6. import org.restlet.Restlet;  
  7. import org.restlet.routing.Router;  
  8.   
  9. /*  
  10.  *   
  11.  *@author yangshuai  
  12.  */   
  13.   
  14. public class PktInHistoryWebRoutable implements RestletRoutable{  
  15.   
  16.     public Restlet getRestlet(Context context){  
  17.         Router router =new Router(context) ;  
  18.         router.attach("/pktinhistory/json", PktInHistoryResource.class) ;  
  19.         return router ;  
  20.     }  
  21.       
  22.     public String basePath(){  
  23.         return "/vm/statics" ;  
  24.     }  
  25. }  


5.資源發佈 

資源綁定相應路徑後需要在REST服務中發佈,因此還需要在PktinHistorystartUp方法中註冊PktInHistoryWebRoutable,表明有新的資源加入REST服務

[html] view plain copy
 print?
  1. @Override  
  2.     public void init(FloodlightModuleContext context)  
  3.             throws FloodlightModuleException {  
  4.         FloodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);  
  5.         restApi = context.getServiceImpl(IRestApiService.class) ;  
  6.     }  


6.定義完上述源碼後還需要在配置文件中指定新增模塊名,該配置文件爲resources/META-INF/services/net.FloodLight.core.module.IFloodLightModule,這裏就是添加net.FloodLightcontroller.statics.PktinHistory模塊配置信息。該配置文件是FloodLight模塊加載系統中加載模塊類的依據,用於告知控制器要加載那些模塊。 


7.除上述配置外,還需要在resources/floodlightdefault.properties中的floodlight.modules配置參數後追加新增模塊名(net.FloodLight.controller.statics.PktinHistory 注:這裏就要根據添加的PktinHistory 類的具體路徑進行修改),表明該配置啓動時必須加載。

 

實驗成果截圖:

發佈了23 篇原創文章 · 獲贊 9 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章