Skip to content

Commit

Permalink
Merge pull request #1760 from OpenC3/timeline_exec
Browse files Browse the repository at this point in the history
Add execute to TimelineModel and api in controller to set it
  • Loading branch information
ryanmelt authored Dec 14, 2024
2 parents 22faade + 204289a commit a5556d6
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 4 deletions.
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

0 comments on commit a5556d6

Please sign in to comment.