Java gets SDN's topo

思路

  • 由于Java调用北向接口过程复杂,故此处编写Python脚本获取拓扑
  • 使用Jython包完成Pyhon脚本的调用
  • 考虑到PythonJava的数据结构难以直接转换,这里选择将脚本获取的拓扑用无向图的形式保存本地文件topo.txt
  • 通过Java读取本地文件,并进行处理分析,发送到前端

实现

Python脚本编写

  • 引入相关包

    1
    2
    3
    import sdn_net as sn
    import networkx as nx
    import json

    此处利用了networkxGraph图结构;json用于将数据转化为字典集;sdn_net是之前写的流表下发和拓扑抽象的脚本,此处引用其中的函数其实就是懒

  • 调用北向接口获取链路信息

    1
    2
    3
    4
    5
    G = nx.Graph()
    status,resp = sn.get_links(ip)
    resp = json.loads(resp)
    for i in resp["links"]:
    G.add_edge(i["src"]["device"],i["dst"]["device"])

    这里使用了Graph做无向图,解决了链路双向的处理问题

  • 写入本地文件

    1
    2
    3
    4
    5
    6
    7
    8
    # 清空文件
    f = open('topo.txt', 'w')
    f.write('')
    f.close()
    # 写入文件
    f = open('topo.txt', 'a')
    for i in G.edges():
    f.write(i[0]+' '+i[1]+'\n')

    因为每次获取链路的状态应更新原来的状态,所以需要每次清空文件再进行写入

    此处如果不写明topo.txt的绝对路径,在之后的Java调用中会默认保存到Java项目目录下

  • 文件形式改为Json

    和前端兄弟商定后,要达到如下效果

    故改装代码

    1
    2
    3
    4
    5
    6
    filename = "{YOUR PATH}/topo.json"
    topo = []
    for i in G.edges():
    topo.append({"a":i[0],"b":i[1]})
    with open(filename, 'w') as file_obj:
    json.dump(topo, file_obj)

    Json对于前端操作更加方便,此处改用Json存储

Java调用Python脚本

  • 导入Jython

    (虽然没用上,万一以后有用呢)

    1. Jython官网下载,得到安装包,使用口令进行安装

      1
      java -jar jython_installer-{VERSION}.jar
    2. 到安装位置找到jython.jar复制放入src->lib

    3. 右键lib,选择add as library即可完成载入

  • Java调用get_topo.py

    • 启用Runtime.getRuntime().exec()函数,由于是在Linux系统下进行,需要修改参数

      1
      2
      String cmd = "python3 {YOUR PATH}/get_topo.py";
      Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", cmd});

      这里的命令行如果含有空格或|需要组合成String形式导入,否则命令不运行