Commit 8201bc3b by source_reader

added edit endpoints for annotations, better logging, and bug fixes

parent 1765b262
...@@ -55,8 +55,8 @@ module Joule ...@@ -55,8 +55,8 @@ module Joule
@backend.module_interface(joule_module, req) @backend.module_interface(joule_module, req)
end end
def module_post_interface(joule_module, req) def module_post_interface(joule_module, req, body)
@backend.module_post_interface(joule_module, req) @backend.module_post_interface(joule_module, req, body)
end end
# === ANNOTATIONS === # === ANNOTATIONS ===
...@@ -88,6 +88,20 @@ module Joule ...@@ -88,6 +88,20 @@ module Joule
# returns nil # returns nil
@backend.delete_annotation(annotation.id) @backend.delete_annotation(annotation.id)
end end
def edit_annotation(id, title, content, stream)
json = @backend.edit_annotation(id, title, content)
annotation = Annotation.new
annotation.id = json["id"]
annotation.title = json["title"]
annotation.content = json["content"]
annotation.start_time = json["start"]
annotation.end_time = json["end"]
# ignore joule stream_id parameter
# use the db_stream model instead
annotation.db_stream = stream
annotation
end
# === END ANNOTATIONS === # === END ANNOTATIONS ===
def node_type def node_type
......
...@@ -18,87 +18,87 @@ module Joule ...@@ -18,87 +18,87 @@ module Joule
end end
def dbinfo def dbinfo
begin begin
resp = self.class.get("#{@url}/version") resp = self.class.get("#{@url}/version")
if not resp.success? if not resp.success?
Rails.logger.warn "Error retrieving /version for #{@url}: [#{resp.body}]" Rails.logger.warn "Error retrieving /version for #{@url}: [#{resp.body}]"
return nil
end
version = resp.parsed_response
resp = self.class.get("#{@url}/dbinfo")
if not resp.success?
Rails.logger.warn "Error retrieving /dbinfo for #{@url}: [#{resp.body}]"
return nil
end
info = resp.parsed_response
rescue StandardError => e
Rails.logger.warn "Error retrieving dbinfo for #{@url}: [#{e}]"
return nil return nil
end end
version = resp.parsed_response # if the site exists but is not a nilm...
required_keys = %w(size other free reserved)
resp = self.class.get("#{@url}/dbinfo") unless info.respond_to?(:has_key?) &&
if not resp.success? required_keys.all? {|s| info.key? s}
Rails.logger.warn "Error retrieving /dbinfo for #{@url}: [#{resp.body}]" Rails.logger.warn "Error #{@url} is not a Joule node"
return nil return nil
end end
info = resp.parsed_response {
rescue StandardError => e version: version,
Rails.logger.warn "Error retrieving dbinfo for #{@url}: [#{e}]" size_db: info['size'],
return nil size_other: info['other'],
end size_total: info['size'] + info['other'] + info['free'] + info['reserved']
# if the site exists but is not a nilm... }
required_keys = %w(size other free reserved)
unless info.respond_to?(:has_key?) &&
required_keys.all? { |s| info.key? s }
Rails.logger.warn "Error #{@url} is not a Joule node"
return nil
end
{
version: version,
size_db: info['size'],
size_other: info['other'],
size_total: info['size'] + info['other'] + info['free'] + info['reserved']
}
end end
def db_schema def db_schema
begin begin
resp = self.class.get("#{@url}/streams.json") resp = self.class.get("#{@url}/streams.json")
return nil unless resp.success? return nil unless resp.success?
rescue StandardError => e rescue StandardError => e
Rails.logger.warn "Error retrieving db_schema for #{@url}: [#{e}]" Rails.logger.warn "Error retrieving db_schema for #{@url}: [#{e}]"
return nil return nil
end end
resp.parsed_response.deep_symbolize_keys resp.parsed_response.deep_symbolize_keys
end end
def module_schemas def module_schemas
begin begin
resp = self.class.get("#{@url}/modules.json?statistics=1") resp = self.class.get("#{@url}/modules.json?statistics=1")
return nil unless resp.success? return nil unless resp.success?
items = resp.parsed_response items = resp.parsed_response
# if the site exists but is not a joule server... # if the site exists but is not a joule server...
required_keys = %w(name inputs outputs) required_keys = %w(name inputs outputs)
items.each do |item| items.each do |item|
unless item.respond_to?(:has_key?) && unless item.respond_to?(:has_key?) &&
required_keys.all? { |s| item.key? s } required_keys.all? {|s| item.key? s}
Rails.logger.warn "Error #{@url} is not a Joule node" Rails.logger.warn "Error #{@url} is not a Joule node"
return nil return nil
end end
item.symbolize_keys! item.symbolize_keys!
end end
rescue StandardError => e rescue StandardError => e
Rails.logger.warn "Error retrieving module_schemas for #{@url}: [#{e}]" Rails.logger.warn "Error retrieving module_schemas for #{@url}: [#{e}]"
return nil return nil
end end
items items
end end
def module_interface(joule_module, req) def module_interface(joule_module, req)
self.class.get("#{@url}/interface/#{joule_module.joule_id}/#{req}") self.class.get("#{@url}/interface/#{joule_module.joule_id}/#{req}")
end end
def module_post_interface(joule_module, req) def module_post_interface(joule_module, req, body)
self.class.post("#{@url}/interface/#{joule_module.joule_id}/#{req}") self.class.post("#{@url}/interface/#{joule_module.joule_id}/#{req}", body: body)
end end
def stream_info(joule_id) def stream_info(joule_id)
begin begin
resp = self.class.get("#{@url}/stream.json?id=#{joule_id}") resp = self.class.get("#{@url}/stream.json?id=#{joule_id}")
return nil unless resp.success? return nil unless resp.success?
rescue rescue
return nil return nil
end end
resp.parsed_response.deep_symbolize_keys resp.parsed_response.deep_symbolize_keys
end end
...@@ -107,10 +107,10 @@ module Joule ...@@ -107,10 +107,10 @@ module Joule
query = {'id': joule_id, 'max-rows': resolution} query = {'id': joule_id, 'max-rows': resolution}
query['start'] = start_time unless start_time.nil? query['start'] = start_time unless start_time.nil?
query['end'] = end_time unless end_time.nil? query['end'] = end_time unless end_time.nil?
options = { query: query} options = {query: query}
begin begin
resp = self.class.get("#{@url}/data.json", options) resp = self.class.get("#{@url}/data.json", options)
if resp.code==400 and resp.body.include?('decimated data is not available') if resp.code == 400 and resp.body.include?('decimated data is not available')
return {success: false, result: "decimation error"} return {success: false, result: "decimation error"}
end end
return {success: false, result: resp.body} unless resp.success? return {success: false, result: resp.body} unless resp.success?
...@@ -124,7 +124,7 @@ module Joule ...@@ -124,7 +124,7 @@ module Joule
query = {'id': joule_id} query = {'id': joule_id}
query['start'] = start_time unless start_time.nil? query['start'] = start_time unless start_time.nil?
query['end'] = end_time unless end_time.nil? query['end'] = end_time unless end_time.nil?
options = { query: query} options = {query: query}
begin begin
resp = self.class.get("#{@url}/data/intervals.json", options) resp = self.class.get("#{@url}/data/intervals.json", options)
return {success: false, result: resp.body} unless resp.success? return {success: false, result: resp.body} unless resp.success?
...@@ -143,51 +143,51 @@ module Joule ...@@ -143,51 +143,51 @@ module Joule
def update_stream(db_stream) def update_stream(db_stream)
elements = [] elements = []
db_stream.db_elements.each do |elem| db_stream.db_elements.each do |elem|
elements << {name: elem.name, elements << {name: elem.name,
plottable: elem.plottable, plottable: elem.plottable,
units: elem.units, units: elem.units,
default_min: elem.default_min, default_min: elem.default_min,
default_max: elem.default_max, default_max: elem.default_max,
scale_factor: elem.scale_factor, scale_factor: elem.scale_factor,
offset: elem.offset, offset: elem.offset,
display_type: elem.display_type} display_type: elem.display_type}
end end
attrs = { name: db_stream.name, attrs = {name: db_stream.name,
description: db_stream.description, description: db_stream.description,
elements: elements elements: elements
} }
begin begin
response = self.class.put("#{@url}/stream.json", response = self.class.put("#{@url}/stream.json",
headers: { 'Content-Type' => 'application/json' }, headers: {'Content-Type' => 'application/json'},
body: { body: {
id: db_stream.joule_id, id: db_stream.joule_id,
stream: attrs}.to_json) stream: attrs}.to_json)
rescue rescue
return { error: true, msg: 'cannot contact Joule server' } return {error: true, msg: 'cannot contact Joule server'}
end end
unless response.success? unless response.success?
return { error: true, msg: "error updating #{db_stream.path} metadata" } return {error: true, msg: "error updating #{db_stream.path} metadata"}
end end
{ error: false, msg: 'success' } {error: false, msg: 'success'}
end end
def update_folder(db_folder) def update_folder(db_folder)
attrs = { name: db_folder.name, attrs = {name: db_folder.name,
description: db_folder.description} description: db_folder.description}
begin begin
response = self.class.put("#{@url}/folder.json", response = self.class.put("#{@url}/folder.json",
headers: { 'Content-Type' => 'application/json' }, headers: {'Content-Type' => 'application/json'},
body: { body: {
id: db_folder.joule_id, id: db_folder.joule_id,
folder: attrs}.to_json) folder: attrs}.to_json)
rescue rescue
return { error: true, msg: 'cannot contact Joule server' } return {error: true, msg: 'cannot contact Joule server'}
end end
unless response.success? unless response.success?
return { error: true, msg: "error updating #{db_folder.path} metadata" } return {error: true, msg: "error updating #{db_folder.path} metadata"}
end end
{ error: false, msg: 'success' } {error: false, msg: 'success'}
end end
# === ANNOTATION METHODS === # === ANNOTATION METHODS ===
...@@ -200,8 +200,8 @@ module Joule ...@@ -200,8 +200,8 @@ module Joule
'end': annotation.end_time} 'end': annotation.end_time}
begin begin
resp = self.class.post("#{@url}/annotation.json", resp = self.class.post("#{@url}/annotation.json",
headers: { 'Content-Type' => 'application/json' }, headers: {'Content-Type' => 'application/json'},
body: data.to_json) body: data.to_json)
raise "error creating annotations #{resp.body}" unless resp.success? raise "error creating annotations #{resp.body}" unless resp.success?
rescue rescue
raise "connection error" raise "connection error"
...@@ -212,7 +212,7 @@ module Joule ...@@ -212,7 +212,7 @@ module Joule
def get_annotations(stream_id) def get_annotations(stream_id)
query = {'stream_id': stream_id} query = {'stream_id': stream_id}
options = { query: query} options = {query: query}
begin begin
resp = self.class.get("#{@url}/annotations.json", options) resp = self.class.get("#{@url}/annotations.json", options)
raise "error loading annotations #{resp.body}" unless resp.success? raise "error loading annotations #{resp.body}" unless resp.success?
...@@ -224,7 +224,7 @@ module Joule ...@@ -224,7 +224,7 @@ module Joule
def delete_annotation(annotation_id) def delete_annotation(annotation_id)
query = {'id': annotation_id} query = {'id': annotation_id}
options = { query: query} options = {query: query}
begin begin
resp = self.class.delete("#{@url}/annotation.json", resp = self.class.delete("#{@url}/annotation.json",
options) options)
...@@ -234,6 +234,21 @@ module Joule ...@@ -234,6 +234,21 @@ module Joule
end end
end end
def edit_annotation(annotation_id, title, content)
begin
resp = self.class.put("#{@url}/annotation.json",
headers: {'Content-Type' => 'application/json'},
body: {id: annotation_id,
title: title,
content: content}.to_json)
raise "error updating annotation #{resp.body}" unless resp.success?
rescue
raise "connection error"
end
resp.parsed_response
end
# === END ANNOTATION METHODS === # === END ANNOTATION METHODS ===
end end
end end
...@@ -95,5 +95,24 @@ module Nilmdb ...@@ -95,5 +95,24 @@ module Nilmdb
end end
@backend.write_annotations(path, updated_annotations) @backend.write_annotations(path, updated_annotations)
end end
def edit_annotation(id, title, content, stream)
path = stream.path
json = @backend.read_annotations(path)
index = json.index{ |item| item['id']== id.to_i}
raise "error, invalid annotation id" if index.nil?
# find the specified id
json[index]['title'] = title
json[index]['content'] = content
@backend.write_annotations(path, json)
annotation = Annotation.new
annotation.id = json[index]["id"]
annotation.title = json[index]["title"]
annotation.content = json[index]["content"]
annotation.start_time = json[index]["start"]
annotation.end_time = json[index]["end"]
annotation.db_stream = stream
annotation
end
end end
end end
...@@ -38,6 +38,22 @@ class AnnotationsController < ApplicationController ...@@ -38,6 +38,22 @@ class AnnotationsController < ApplicationController
render :index render :index
end end
# PATCH/PUT /annotations/1.json
def update
@service = StubService.new
begin
annotation = @node_adapter.edit_annotation(params[:id],
params[:title],
params[:content],
@db_stream)
rescue RuntimeError => e
@service.add_error("Cannot update annotation [#{e}]")
render 'helpers/empty_response', status: :unprocessable_entity and return
end
@annotations = [annotation]
render :index
end
# DELETE /annotations/1.json # DELETE /annotations/1.json
def destroy def destroy
annotation = Annotation.new annotation = Annotation.new
......
...@@ -47,7 +47,7 @@ class InterfacesController < ActionController::Base ...@@ -47,7 +47,7 @@ class InterfacesController < ActionController::Base
def post def post
path = create_proxy_path(request.fullpath, @joule_module.id) path = create_proxy_path(request.fullpath, @joule_module.id)
proxied_response = @node_adapter.module_post_interface(@joule_module,path) proxied_response = @node_adapter.module_post_interface(@joule_module,path, request.raw_post)
render plain: proxied_response.body render plain: proxied_response.body
proxied_response.headers.each do |key,value| proxied_response.headers.each do |key,value|
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment