【问题标题】:Bulbs: g.scripts.update() : TypeError: sequence item 2: expected string or Unicode, NoneType found灯泡:g.scripts.update():TypeError:序列项 2:预期的字符串或 Unicode,找到 NoneType
【发布时间】:2014-09-10 04:41:26
【问题描述】:

我正在使用 TitanGraphDB + Cassandra。我按如下方式启动Titan

cd titan-cassandra-0.3.1
bin/titan.sh config/titan-server-rexster.xml config/titan-server-cassandra.properties

我有一个 Rexster shell,可以用来与上面的 Titan + Cassandra 通信。

cd rexster-console-2.3.0
bin/rexster-console.sh

我正在尝试使用 Titan Graph DB 对网络拓扑进行建模。我想从我的 python 程序中对 Titan Graph DB 进行编程。我为此使用灯泡包。 我创建了五种类型的顶点

 - switch
 - port 
 - device
 - flow
 - flow_entry

我在逻辑连接的顶点之间创建边。边缘没有标记。

假设我想测试Vertex AVertex B之间的连通性

我有一个 groovy 脚本 is_connected.groovy

def isConnected (portA, portB) {
    return portA.both().retain([portB]).hasNext()
}

现在从我的 rexster 控制台

g = rexster.getGraph("graph")
==>titangraph[embeddedcassandra:null]
rexster[groovy]> g.V('type', 'flow')    
==>v[116]
==>v[100]
rexster[groovy]> g.V('type', 'flow_entry')
==>v[120]
==>v[104]

正如您在上面看到的,我有两个流类型的顶点v[116]v[100]

我有两个类型为 flow_entry v[120]v[104] 的顶点

我想检查v[120]v[116] 之间的连通性,例如

rexster[groovy]> ?e is_connected.groovy       
==>null
rexster[groovy]> is_connected(g.v(116),g.v(120))
==>true

到目前为止一切顺利。现在我希望能够从我的导入灯泡包的 python 程序中使用这个脚本。

我的目录结构如下。

Projects/ryu
        --> ryu/app_simple_switch.py

Projects/ryu_extras
        --> rexster-console-2.3.0
        --> titan-cassandra-0.3.1

我的脚本 is_connected.groovy 包含 isConnected() 函数/程序保存在Projects/ryu_extras/rexster-console-2.3.0

现在,我在Projects/ryu/ryu/app/simple_switch.py 中的python 程序中尝试执行以下操作。

self.g.scripts.update('Projects/ryu_extras/rexster-console-2.3.0/is_connected.groovy')        # add file to scripts index
script = self.g.scripts.get('isConnected')      # get a function by its name
params = dict(portA=flow,portB=fe1)             # put function params in dict
items = self.g.gremlin.query(script, params)
self.create_outgoing_edge(flow,fe1)
self.create_outgoing_edge(fe1,sw_vertex)

我收到以下错误。

hub: uncaught exception: Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/ryu/lib/hub.py", line 48, in _launch
    func(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/ryu/base/app_manager.py", line 256, in _event_loop
    handler(ev)
  File "/home/karthik/Projects/ryu/ryu/app/simple_switch.py", line 322, in _packet_in_handler
    self.compute_path(src,dst,datapath)
  File "/home/karthik/Projects/ryu/ryu/app/simple_switch.py", line 289, in compute_path
    self.g.scripts.update('/home/karthik/Projects/ryu_extras/rexster-console-2.3.0/is_connected.groovy')   # add file to scripts index
  File "/usr/local/lib/python2.7/dist-packages/bulbs/groovy.py", line 120, in update
    methods = self._get_methods(file_path)
  File "/usr/local/lib/python2.7/dist-packages/bulbs/groovy.py", line 160, in _get_methods
    return Parser(file_path).get_methods()
  File "/usr/local/lib/python2.7/dist-packages/bulbs/groovy.py", line 255, in __init__
    Scanner(handlers).scan(groovy_file)
  File "/usr/local/lib/python2.7/dist-packages/bulbs/groovy.py", line 246, in scan
    self.get_item(fin,line)
  File "/usr/local/lib/python2.7/dist-packages/bulbs/groovy.py", line 236, in get_item
    content = "\n".join(sections).strip()
TypeError: sequence item 2: expected string or Unicode, NoneType found

如您所见,错误在 scripts.update() 函数中。我似乎无法弄清楚我做错了什么。任何帮助将不胜感激。

【问题讨论】:

    标签: groovy titan bulbs rexster


    【解决方案1】:

    您需要将脚本保存在名为gremlin.groovy 的文件中,或者在从 Bulbs 脚本索引中获取脚本时指定脚本的命名空间。

    与 Rexster 一样,Bulbs 使用 Groovy 文件名的第一部分作为命名空间。

    例如,gremlin.groovy 文件中定义的方法被添加到 Bulbs gremlin 命名空间。

    Bulbs 的所有预定义 Gremlin 脚本都定义在 gremlin.groovy 文件中,因此 gremlin 是默认命名空间:

    您的应用中可以有多个/额外的gremlin.groovy 文件。如果您想将所有内容保留在同一个命名空间下,或者您想覆盖预定义的方法,请执行此操作:

    >>> g.scripts.update("/path/to/gremlin.groovy") # add scripts to gremlin namespace
    

    看... https://github.com/espeed/bulbs/blob/f666fa89b3c99bc0a6b4e964aa1bff70b05a2e96/bulbs/groovy.py#L112

    您可以通过在名称为 myapp.groovysomemodel.groovy 的文件中定义 Gremlin 方法来创建特定于应用程序和特定于模型的命名空间:

    >>> g.scripts.update("/path/to/myapp.groovy")     # add scripts to myapp namespace
    >>> g.scripts.update("/path/to/somemodel.groovy") # add scripts to somemodel namespace
    

    然后要获取特定命名空间下的脚本,请执行以下操作:

    >>> script = g.scripts.get('myapp:isConnected')      # use prefix notation, or...
    >>> script = g.scripts.get('isConnected', 'myapp')   # specify namespace as arg
    

    看... https://github.com/espeed/bulbs/blob/f666fa89b3c99bc0a6b4e964aa1bff70b05a2e96/bulbs/groovy.py#L77

    要为每个命名空间生成连接的服务器端脚本文件,请使用g.make_script_files() 方法:

    >>> g.make_script_files() # write files to the current dir, or...
    >>> g.make_script_files("/path/to/scripts/dir")    # write files to specified dir
    

    make_scripte_files() 方法将为每个命名空间创建一个单独的.groovy 文件。如果您覆盖命名空间中的方法,则生成的文件中只会包含最新的方法。

    看... https://github.com/espeed/bulbs/blob/f666fa89b3c99bc0a6b4e964aa1bff70b05a2e96/bulbs/rexster/graph.py#L62

    更多详情,请参阅...

    【讨论】:

      【解决方案2】:

      可能有一种“灯泡方式”可以做到这一点,但您可以尝试通过将您的函数放在 Rexster 的服务器上来全局公开您的函数。然后在<script-engine><init-scripts> 部分中,您可以添加您的is_connected.groovy。示例 rexster.xml 应该已经有这样的示例:

      <script-engines>
          <script-engine>
              <name>gremlin-groovy</name>
              <reset-threshold>-1</reset-threshold>
              <init-scripts>config/is_connected.groovy</init-scripts>
              <imports>com.tinkerpop.rexster.client.*</imports>
              <static-imports>java.lang.Math.PI</static-imports>
          </script-engine>
      </script-engines>
      

      【讨论】:

        猜你喜欢
        • 2012-12-22
        • 1970-01-01
        • 2018-04-27
        • 1970-01-01
        • 2017-06-05
        • 1970-01-01
        • 2020-04-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多