Skip to content

Commit

Permalink
The test/rest/example.rb now works with the latest sinatra from github
Browse files Browse the repository at this point in the history
Moved the RestMixin inside the Neo4j name space.
Fixed a Sinatra start/stop issues - have to join the thread so that sintatra does not exit on start up.
 [#26]
  • Loading branch information
andreas committed Jun 19, 2009
1 parent ab26bbc commit 8139a2a
Show file tree
Hide file tree
Showing 3 changed files with 180 additions and 157 deletions.
313 changes: 160 additions & 153 deletions lib/neo4j/extensions/rest.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,190 +13,200 @@
#
# TODO delete and RESTful transaction (which will map to neo4j transactions)
#
module RestMixin
module Neo4j

#URL_REGEXP = Regexp.new '((http[s]?|ftp):\/)?\/?([^:\/\s]+)((\/\w+)*\/)([\w\-\.]+[^#?\s]+)(.*)?(#[\w\-]+)?$'
URL_REGEXP = Regexp.new '((http[s]?|ftp):\/)?\/?([^:\/\s]+)((\/\w+)*\/)([\w\-\.]+[^#?\s]+)$'
module RestMixin

#URL_REGEXP = Regexp.new '((http[s]?|ftp):\/)?\/?([^:\/\s]+)((\/\w+)*\/)([\w\-\.]+[^#?\s]+)(.*)?(#[\w\-]+)?$'
URL_REGEXP = Regexp.new '((http[s]?|ftp):\/)?\/?([^:\/\s]+)((\/\w+)*\/)([\w\-\.]+[^#?\s]+)$'


Sinatra::Application.get("/test") do
# content_type :html
"<html><body><h2>Neo4j.rb is alive !</h2></body></html>"
end

Sinatra::Application.post("/neo") do
body = request.body.read
Object.class_eval body
200
end
Sinatra::Application.get("/test") do
# content_type :html
"<html><body><h2>Neo4j.rb is alive !</h2></body></html>"
end

Sinatra::Application.get("/relations/:id") do
content_type :json
Neo4j::Transaction.run do
rel = Neo4j.load_relationship(params[:id].to_i)
return 404, "Can't find relationship with id #{params[:id]}" if rel.nil?
rel.props.to_json
Sinatra::Application.post("/neo") do
body = request.body.read
Object.class_eval body
200
end
end

Sinatra::Application.get("/relations/:id") do
content_type :json
Neo4j::Transaction.run do
rel = Neo4j.load_relationship(params[:id].to_i)
return 404, "Can't find relationship with id #{params[:id]}" if rel.nil?
rel.props.to_json
end
end

def _uri
"#{_base_uri}/nodes/#{self.class.to_s}/#{self.neo_node_id}"
end

def _base_uri
host = Sinatra::Application.host
port = Sinatra::Application.port
"http://#{host}:#{port}"
end
def _uri
"#{_base_uri}/nodes/#{self.class.to_s}/#{self.neo_node_id}"
end

def _base_uri
host = Sinatra::Application.host
port = Sinatra::Application.port
"http://#{host}:#{port}"
end

def self.included(c)
classname = c.to_s

#puts "Register Neo Node Class /nodes/#{classname}"
def self.included(c)
classname = c.to_s

#puts "Register Neo Node Class /nodes/#{classname}"

Sinatra::Application.get("/nodes/#{classname}/:id/traverse") do
content_type :json
Neo4j::Transaction.run do
node = Neo4j.load(params[:id])
return 404, "Can't find node with id #{params[:id]}" if node.nil?

relation = params['relation']
depth = params['depth']
depth ||= 1
uris = node.traverse.outgoing(relation.to_sym).depth(depth.to_i).collect{|node| node._uri}
{'uri_list' => uris}.to_json

Sinatra::Application.get("/nodes/#{classname}/:id/traverse") do
content_type :json
Neo4j::Transaction.run do
node = Neo4j.load(params[:id])
return 404, "Can't find node with id #{params[:id]}" if node.nil?

relation = params['relation']
depth = params['depth']
depth ||= 1
uris = node.traverse.outgoing(relation.to_sym).depth(depth.to_i).collect{|node| node._uri}
{'uri_list' => uris}.to_json
end
end
end


Sinatra::Application.get("/nodes/#{classname}/:id/:prop") do
content_type :json
Neo4j::Transaction.run do
node = Neo4j.load(params[:id])
return 404, "Can't find node with id #{params[:id]}" if node.nil?
prop = params[:prop].to_sym
if node.class.relationships_info.keys.include?(prop)
rels = node.send(prop) || []
rels.map{|rel| rel.props}.to_json
else
{prop => node.get_property(prop)}.to_json
Sinatra::Application.get("/nodes/#{classname}/:id/:prop") do
content_type :json
Neo4j::Transaction.run do
node = Neo4j.load(params[:id])
return 404, "Can't find node with id #{params[:id]}" if node.nil?
prop = params[:prop].to_sym
if node.class.relationships_info.keys.include?(prop)
rels = node.send(prop) || []
rels.map{|rel| rel.props}.to_json
else
{prop => node.get_property(prop)}.to_json
end
end
end
end


Sinatra::Application.post("/nodes/#{classname}/:id/:rel") do
content_type :json
Neo4j::Transaction.run do
node = Neo4j.load(params[:id])
rel = params[:rel]
Sinatra::Application.post("/nodes/#{classname}/:id/:rel") do
content_type :json
Neo4j::Transaction.run do
node = Neo4j.load(params[:id])
rel = params[:rel]

# does this relationship exist ?
if !node.class.relationships_info.keys.include?(rel.to_sym)
return 409, "Can't add relation on '#{rel}' since it does not exist"
end
body = request.body.read
data = JSON.parse(body)
uri = data['uri']
match = URL_REGEXP.match(uri)
return 400, "Bad node uri '#{uri}'" if match.nil?
to_clazz, to_node_id = match[6].split('/')

other_node = Neo4j.load(to_node_id.to_i)
return 400, "Unknown other node with id '#{to_node_id}'" if other_node.nil?

if to_clazz != other_node.class.to_s
return 400, "Wrong type id '#{to_node_id}' expected '#{to_clazz}' got '#{other_node.class.to_s}'"
end
# does this relationship exist ?
if !node.class.relationships_info.keys.include?(rel.to_sym)
return 409, "Can't add relation on '#{rel}' since it does not exist"
end
body = request.body.read
data = JSON.parse(body)
uri = data['uri']
match = URL_REGEXP.match(uri)
return 400, "Bad node uri '#{uri}'" if match.nil?
to_clazz, to_node_id = match[6].split('/')

rel_obj = node.send(rel).new(other_node)
other_node = Neo4j.load(to_node_id.to_i)
return 400, "Unknown other node with id '#{to_node_id}'" if other_node.nil?

return 400, "Can't create relationship to #{to_clazz}" if rel_obj.nil?
if to_clazz != other_node.class.to_s
return 400, "Wrong type id '#{to_node_id}' expected '#{to_clazz}' got '#{other_node.class.to_s}'"
end

# create URI
redirect "/relations/#{rel_obj.neo_relationship_id.to_s}", 201 # created
rel_obj = node.send(rel).new(other_node)

return 400, "Can't create relationship to #{to_clazz}" if rel_obj.nil?

# create URI
redirect "/relations/#{rel_obj.neo_relationship_id.to_s}", 201 # created
end
end
end


Sinatra::Application.put("/nodes/#{classname}/:id/:prop") do
content_type :json
Neo4j::Transaction.run do
node = Neo4j.load(params[:id])
property = params[:prop]
body = request.body.read
data = JSON.parse(body)
value = data[property]
return 409, "Can't set property #{property} with JSON data '#{body}'" if value.nil?
node.set_property(property, value)
200
Sinatra::Application.put("/nodes/#{classname}/:id/:prop") do
content_type :json
Neo4j::Transaction.run do
node = Neo4j.load(params[:id])
property = params[:prop]
body = request.body.read
data = JSON.parse(body)
value = data[property]
return 409, "Can't set property #{property} with JSON data '#{body}'" if value.nil?
node.set_property(property, value)
200
end
end
end

Sinatra::Application.get("/nodes/#{classname}/:id") do
content_type :json
Neo4j::Transaction.run do
node = Neo4j.load(params[:id])
return 404, "Can't find node with id #{params[:id]}" if node.nil?
node.props.to_json
Sinatra::Application.get("/nodes/#{classname}/:id") do
content_type :json
Neo4j::Transaction.run do
node = Neo4j.load(params[:id])
return 404, "Can't find node with id #{params[:id]}" if node.nil?
node.props.to_json
end
end
end

Sinatra::Application.put("/nodes/#{classname}/:id") do
content_type :json
Neo4j::Transaction.run do
body = request.body.read
data = JSON.parse(body)
node = Neo4j.load(params[:id])
node.update(data, true)
response = node.props.to_json
response
Sinatra::Application.put("/nodes/#{classname}/:id") do
content_type :json
Neo4j::Transaction.run do
body = request.body.read
data = JSON.parse(body)
node = Neo4j.load(params[:id])
node.update(data, true)
response = node.props.to_json
response
end
end
end

Sinatra::Application.delete("/nodes/#{classname}/:id") do
content_type :json
Neo4j::Transaction.run do
node = Neo4j.load(params[:id])
return 404, "Can't find node with id #{params[:id]}" if node.nil?
node.delete
""
Sinatra::Application.delete("/nodes/#{classname}/:id") do
content_type :json
Neo4j::Transaction.run do
node = Neo4j.load(params[:id])
return 404, "Can't find node with id #{params[:id]}" if node.nil?
node.delete
""
end
end
end

Sinatra::Application.post("/nodes/#{classname}") do
content_type :json
Neo4j::Transaction.run do
p = c.new
data = JSON.parse(request.body.read)
puts "POST DATA #{data.inspect} TO #{p}"
p.update(data)
puts "POSTED #{p}"
redirect "/nodes/#{classname}/#{p.neo_node_id.to_s}", 201 # created
Sinatra::Application.post("/nodes/#{classname}") do
content_type :json
Neo4j::Transaction.run do
p = c.new
data = JSON.parse(request.body.read)
puts "POST DATA #{data.inspect} TO #{p}"
p.update(data)
puts "POSTED #{p}"
redirect "/nodes/#{classname}/#{p.neo_node_id.to_s}", 201 # created
end
end
end

Sinatra::Application.get("/nodes/#{classname}") do
content_type :json
Neo4j::Transaction.run do
resources =
if params[:search].nil?
c.all.map{|rel| rel.end_node}
else
puts "Search string: #{params[:search]}"
c.find(params[:search])
end
resources.map{|res| res.props}.to_json
Sinatra::Application.get("/nodes/#{classname}") do
content_type :json
Neo4j::Transaction.run do
resources =
if params[:search].nil?
c.all.map{|rel| rel.end_node}
else
puts "Search string: #{params[:search]}"
c.find(params[:search])
end
resources.map{|res| res.props}.to_json
end
end
end
end


# The RESTful Neo4j server
# Listens for Neo4j start and stops events and starts the server
# when neo4j starts, and stops the rest server when neo4j stops.
#
class RestServer
class << self
attr_accessor :thread

def on_neo_started(neo_instance)
start
end
Expand All @@ -207,40 +217,37 @@ def on_neo_stopped(neo_instance)


def start
puts "start rest server"
puts "RESTful already started" if @sinatra
return if @sinatra
return if @thread

@sinatra = Thread.new do
puts "HELLO"
puts "Start Restful server at port #{Config[:rest_port]}"
@thread = Thread.new do
puts "Started Restful Neo4j server at port #{Config[:rest_port]}"
Sinatra::Application.run! :port => Config[:rest_port]
puts "Restful server started"
# end
# @sinatra.join
end
end

def stop
if @sinatra
if @thread
# TODO must be a nicer way to do this - to shutdown sinatra
@sinatra.kill
@sinatra = nil
puts "Stop RESTful Neo4j server"
@thread.kill
@thread = nil
end
end
end
end


# Register the RestServer with the event handler
# Configure the rest server default port to 9123
def self.load_rest
puts "LOAD REST"
Neo4j::Config.defaults[:rest_port] = 9123
puts "----"
Neo4j.event_handler.add(RestServer)
puts "LOAD REST EXIT"
end

load_rest


end


Expand Down
Loading

0 comments on commit 8139a2a

Please sign in to comment.