Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add execute to TimelineModel and api in controller to set it #1760

Merged
merged 2 commits into from
Dec 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 49 additions & 1 deletion openc3-cosmos-cmd-tlm-api/app/controllers/timeline_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,55 @@ def color
return
end
begin
model.update_color(color: params['color'])
# Model color=(value) method handles the color validation
model.color = params['color']
model.update()
model.notify(kind: 'updated')
render json: model.as_json(:allow_nan => true)
rescue RuntimeError, JSON::ParserError => e
log_error(e)
render json: { status: 'error', message: e.message, type: e.class }, status: 400
rescue TypeError => e
log_error(e)
render json: { status: 'error', message: 'Invalid json object', type: e.class }, status: 400
rescue OpenC3::TimelineInputError => e
log_error(e)
render json: { status: 'error', message: e.message, type: e.class }, status: 400
end
end

# Set the timeline execution status
#
# name [String] the timeline name, `system42`
# scope [String] the scope of the timeline, `TEST`
# json [String] The json of the timeline name (see below)
# @return [String] the timeline converted into json format
# Request Headers
#```json
# {
# "Authorization": "token/password",
# "Content-Type": "application/json"
# }
#```
# Request Post Body
#```json
# {
# "enable": "false"
# }
#```
def execute
return unless authorization('script_run')
model = @model_class.get(name: params[:name], scope: params[:scope])
if model.nil?
render json: {
status: 'error',
message: "failed to find timeline: #{params[:name]}",
}, status: 404
return
end
begin
# Model execute=(value) method handles the conversion of the string to a boolean
model.execute = params['enable']
model.update()
model.notify(kind: 'updated')
render json: model.as_json(:allow_nan => true)
Expand Down
1 change: 1 addition & 0 deletions openc3-cosmos-cmd-tlm-api/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
resources :timeline, only: [:index, :create]
get '/timeline/:name', to: 'timeline#show', name: /[^\/]+/
post '/timeline/:name/color', to: 'timeline#color', name: /[^\/]+/
post '/timeline/:name/execute', to: 'timeline#execute', name: /[^\/]+/
delete '/timeline/:name', to: 'timeline#destroy', name: /[^\/]+/

post '/timeline/activities/create', to: 'activity#multi_create'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,26 @@
end
end

describe "POST execute" do
it "returns a json hash of name and status code 200" do
post :create, params: {"scope"=>"DEFAULT", "name" => "test"}
expect(response).to have_http_status(:created)
json = JSON.parse(response.body, :allow_nan => true, :create_additions => true)
expect(json["name"]).to eql("test")
expect(json["execute"]).to be true
post :execute, params: {"scope"=>"DEFAULT", "name"=>"test", "enable" => "FALSE"}
expect(response).to have_http_status(:ok)
json = JSON.parse(response.body, :allow_nan => true, :create_additions => true)
expect(json["name"]).to eql("test")
expect(json["execute"]).to be false
post :execute, params: {"scope"=>"DEFAULT", "name"=>"test", "enable" => "true"}
expect(response).to have_http_status(:ok)
json = JSON.parse(response.body, :allow_nan => true, :create_additions => true)
expect(json["name"]).to eql("test")
expect(json["execute"]).to be true
end
end

describe "POST error" do
it "returns a hash and status code 400" do
post :create, params: {"scope"=>"DEFAULT"}
Expand Down
15 changes: 12 additions & 3 deletions openc3/lib/openc3/models/timeline_model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,16 @@
require 'openc3/models/activity_model'
require 'openc3/models/microservice_model'
require 'openc3/topics/timeline_topic'
require 'openc3/config/config_parser'

module OpenC3
class TimelineError < StandardError; end

class TimelineInputError < TimelineError; end

class TimelineModel < Model
attr_reader :execute

PRIMARY_KEY = 'openc3_timelines'.freeze # MUST be equal to ActivityModel::PRIMARY_KEY without leading __
KEY = '__TIMELINE__'.freeze

Expand Down Expand Up @@ -74,7 +77,7 @@ def self.from_json(json, name:, scope:)
self.new(**json.transform_keys(&:to_sym), name: name, scope: scope)
end

def initialize(name:, scope:, updated_at: nil, color: nil, shard: 0)
def initialize(name:, scope:, updated_at: nil, color: nil, shard: 0, execute: true)
if name.nil? || scope.nil?
raise TimelineInputError.new "name or scope must not be nil"
end
Expand All @@ -83,10 +86,11 @@ def initialize(name:, scope:, updated_at: nil, color: nil, shard: 0)
@updated_at = updated_at
@timeline_name = name
@shard = shard.to_i # to_i to handle nil
update_color(color: color)
self.color = color
self.execute = execute
end

def update_color(color: nil)
def color=(color)
if color.nil?
color = '#%06x' % (rand * 0xffffff)
end
Expand All @@ -100,11 +104,16 @@ def update_color(color: nil)
@color = color
end

def execute=(value)
@execute = ConfigParser.handle_true_false(value)
end

# @return [Hash] generated from the TimelineModel
def as_json(*a)
{
'name' => @timeline_name,
'color' => @color,
'execute' => @execute,
'shard' => @shard,
'scope' => @scope,
'updated_at' => @updated_at
Expand Down
Loading