diff --git a/build/ruby/.gitignore b/build/ruby/.gitignore index cb18a88..5decf0a 100644 --- a/build/ruby/.gitignore +++ b/build/ruby/.gitignore @@ -11,4 +11,6 @@ .rspec_status # generated ruby files +lib/tucana/actions/*.rb lib/tucana/internal/*.rb +lib/tucana/shared/*.rb diff --git a/build/ruby/Rakefile b/build/ruby/Rakefile index c79660b..459c594 100644 --- a/build/ruby/Rakefile +++ b/build/ruby/Rakefile @@ -9,48 +9,77 @@ RSpec::Core::RakeTask.new(:spec) PROJECT_ROOT = File.expand_path("../..", __dir__) RUBY_ROOT = "#{PROJECT_ROOT}/build/ruby".freeze -INPUT_INTERNAL_DIR = "#{PROJECT_ROOT}/internal".freeze +PROTO_ROOT = "#{PROJECT_ROOT}/proto".freeze +INPUT_ACTIONS_DIR = "#{PROTO_ROOT}/actions".freeze +INPUT_INTERNAL_DIR = "#{PROTO_ROOT}/internal".freeze +INPUT_SHARED_DIR = "#{PROTO_ROOT}/shared".freeze +OUTPUT_ACTIONS_DIR = "#{RUBY_ROOT}/lib/tucana/actions".freeze OUTPUT_INTERNAL_DIR = "#{RUBY_ROOT}/lib/tucana/internal".freeze +OUTPUT_SHARED_DIR = "#{RUBY_ROOT}/lib/tucana/shared".freeze def system!(*args) system(*args, exception: true) end namespace :generate_ruby do - desc "Generate ruby files for the internal protocol" - task :internal do - FileUtils.rm_rf(OUTPUT_INTERNAL_DIR) - FileUtils.mkdir_p(OUTPUT_INTERNAL_DIR) + def compile_protos!(input_dir, output_dir) + FileUtils.rm_rf(output_dir) + FileUtils.mkdir_p(output_dir) FileUtils.chdir RUBY_ROOT do - Dir["#{INPUT_INTERNAL_DIR}/*.proto"].each do |file| + Dir["#{input_dir}/*.proto"].each do |file| # rubocop:disable Layout/LineLength - system!("bundle exec grpc_tools_ruby_protoc -I #{INPUT_INTERNAL_DIR} --ruby_out=#{OUTPUT_INTERNAL_DIR} --grpc_out=#{OUTPUT_INTERNAL_DIR} #{file}") + system!("bundle exec grpc_tools_ruby_protoc -I #{input_dir} -I #{INPUT_SHARED_DIR} --ruby_out=#{output_dir} --grpc_out=#{output_dir} #{file}") # rubocop:enable Layout/LineLength end - Dir["#{OUTPUT_INTERNAL_DIR}/*_pb.rb"].each do |file| + + Dir["#{OUTPUT_SHARED_DIR}/*_pb.rb"].each do |shared_file| + shared_file_name = File.basename(shared_file).delete_suffix('.rb') + Dir["#{output_dir}/*_pb.rb"].each do |file| + code = File.read(file) + code = code.gsub("require '#{shared_file_name}'", "require_relative '../shared/#{shared_file_name}'") + File.write(file, code) + end + end + + Dir["#{output_dir}/*_pb.rb"].each do |file| code = File.read(file) code = code.gsub(/require '(\S+)_pb'/, "require_relative '\\1_pb'") - File.write(file, code) + File.write(file, code) end end end + desc "Generate ruby files for shared files between protocols" + task :shared do + compile_protos!(INPUT_SHARED_DIR, OUTPUT_SHARED_DIR) + end + + desc "Generate ruby files for the internal protocol" + task internal: "generate_ruby:shared" do + compile_protos!(INPUT_INTERNAL_DIR, OUTPUT_INTERNAL_DIR) + end + + desc "Generate ruby files for the actions protocol" + task actions: "generate_ruby:shared" do + compile_protos!(INPUT_ACTIONS_DIR, OUTPUT_ACTIONS_DIR) + end + desc "Generate ruby files for all protocols" - task all: ["generate_ruby:internal"] + task all: %w[generate_ruby:internal generate_ruby:actions] end namespace :release do desc "Set the version for the gem" task :version, [:version] do |_, args| File.write("#{RUBY_ROOT}/lib/tucana/version.rb", <<~RUBY) - # frozen_string_literal: true + # frozen_string_literal: true - # this file is managed with the "release:version" task. - # to update the version, run "bundle exec rake release:version[NEW_VERSION]". + # this file is managed with the "release:version" task. + # to update the version, run "bundle exec rake release:version[NEW_VERSION]". - module Tucana - VERSION = "#{args[:version]}" - end + module Tucana + VERSION = "#{args[:version]}" + end RUBY system!("bundle") diff --git a/build/ruby/spec/tucana_spec.rb b/build/ruby/spec/tucana_spec.rb index f4df177..7b8941b 100644 --- a/build/ruby/spec/tucana_spec.rb +++ b/build/ruby/spec/tucana_spec.rb @@ -4,4 +4,12 @@ it "has a version number" do expect(Tucana::VERSION).not_to be_nil end + + it "can load internal protocol" do + expect { Tucana.load_protocol(:internal) }.not_to raise_error + end + + it "can load actions protocol" do + expect { Tucana.load_protocol(:actions) }.not_to raise_error + end end diff --git a/build/rust/build.rs b/build/rust/build.rs index 9f338ed..c0eac72 100644 --- a/build/rust/build.rs +++ b/build/rust/build.rs @@ -3,32 +3,40 @@ use std::io::Result; fn main() -> Result<()> { - let path = "src/internal"; + let proto = &[ + "definitions.proto", + "flow_definition.proto", + "node.proto", + "flow.proto", + "action.proto", + "transfer.proto", + "ping.proto" + ]; - if !std::path::Path::new(&path).exists() { - create_dir(path)?; + let inclusions = &[ + "../../proto/shared", + "../../proto/internal", + "../../proto/actions", + ]; + + let out_path = "src/generated"; + + if !std::path::Path::new(&out_path).exists() { + create_dir(out_path)?; } tonic_build::configure() - .out_dir(path) + .out_dir(out_path) .build_server(true) .build_client(true) - .type_attribute("Variable", "#[derive(serde::Serialize, serde::Deserialize)]") - .type_attribute("RuleType", "#[derive(serde::Serialize, serde::Deserialize)]") - .type_attribute("Rule", "#[derive(serde::Serialize, serde::Deserialize)]") - .type_attribute("Type", "#[derive(serde::Serialize, serde::Deserialize)]") + .type_attribute("FlowDefinition", "#[derive(serde::Serialize, serde::Deserialize)]") + .type_attribute("RuntimeFunctionDefinition", "#[derive(serde::Serialize, serde::Deserialize)]") + .type_attribute("RuntimeParameterDefinition", "#[derive(serde::Serialize, serde::Deserialize)]") .type_attribute("Parameter", "#[derive(serde::Serialize, serde::Deserialize)]") .type_attribute("Node", "#[derive(serde::Serialize, serde::Deserialize)]") .type_attribute("Flow", "#[derive(serde::Serialize, serde::Deserialize)]") - .compile(&[ - "variable.proto", - "rule.proto", - "type.proto", - "node.proto", - "flow.proto", - "ping.proto", - ], &["../../internal"]) - .expect("Cannot compile protos"); + .compile(proto, inclusions) + .expect("Cannot compile internal protos"); Ok(()) } \ No newline at end of file diff --git a/build/rust/src/lib.rs b/build/rust/src/lib.rs index 0e01a6e..1a02dce 100644 --- a/build/rust/src/lib.rs +++ b/build/rust/src/lib.rs @@ -1,3 +1,11 @@ pub mod internal { - include!("internal/internal.rs"); + include!("generated/internal.rs"); +} + +pub mod actions { + include!("generated/actions.rs"); +} + +pub mod shared { + include!("generated/shared.rs"); } \ No newline at end of file diff --git a/internal/flow.proto b/internal/flow.proto deleted file mode 100644 index 5695c76..0000000 --- a/internal/flow.proto +++ /dev/null @@ -1,59 +0,0 @@ -syntax = "proto3"; - -option ruby_package = "Tucana::Internal"; - -package internal; - -import "node.proto"; -import "type.proto"; -import "variable.proto"; - -message Flow { - int64 flow_id = 1; - Node starting_node = 2; - repeated Type types = 3; - repeated Variable context = 4; - int64 last_updated = 5; -} - -//Sagittarius sends flow to be updated -message FlowUpdateRequest { - Flow updated_flow = 1; -} - -//Aquila response with success or retry of update -message FlowUpdateResponse { - bool success = 1; -} - -//Sagittarius sends flow_id to be updated -message FlowDeleteRequest { - int64 flow_id = 1; -} - -//Aquila response with success or retry of deletion -message FlowDeleteResponse { - bool success = 1; -} - -//All ids of flows that Aquila holds -message FlowGetRequest { - repeated int64 flow_ids = 1; -} - -//Sagittarius checks if he holds the flow_ids that Aquila sent -//If id is present --> sends flow -//If id is not present --> returns id to be deleted -message FlowGetResponse { - repeated Flow updated_flows = 1; - repeated int64 deleted_flow_ids = 2; -} - -service FlowAquilaService { - rpc Update (FlowUpdateRequest) returns (FlowUpdateResponse) {} - rpc Delete (FlowDeleteRequest) returns (FlowDeleteResponse) {} -} - -service FlowSagittariusService { - rpc Get (FlowGetRequest) returns (FlowGetResponse) {} -} \ No newline at end of file diff --git a/internal/node.proto b/internal/node.proto deleted file mode 100644 index 79c7942..0000000 --- a/internal/node.proto +++ /dev/null @@ -1,24 +0,0 @@ -syntax = "proto3"; - -option ruby_package = "Tucana::Internal"; - -package internal; - -import "variable.proto"; - -message Node { - int64 node_id = 1; - repeated Parameter parameter = 2; - optional string return_type = 3; - optional Node next_node = 4; - repeated Variable context = 5; -} - -message Parameter { - int64 parameter_id = 1; - string name = 2; - string type = 3; - optional string value = 4; - optional Node sub_node = 5; - optional int32 type_ref = 6; -} diff --git a/internal/rule.proto b/internal/rule.proto deleted file mode 100644 index d7305d0..0000000 --- a/internal/rule.proto +++ /dev/null @@ -1,16 +0,0 @@ -syntax = "proto3"; - -option ruby_package = "Tucana::Internal"; - -package internal; - -enum RuleType { - REGEX = 0; - NUMBER_RANGE = 1; - ITEM_OF_COLLECTION = 2; -} - -message Rule { - RuleType type = 1; - string config = 2; -} \ No newline at end of file diff --git a/internal/type.proto b/internal/type.proto deleted file mode 100644 index 50e640a..0000000 --- a/internal/type.proto +++ /dev/null @@ -1,15 +0,0 @@ -syntax = "proto3"; - -option ruby_package = "Tucana::Internal"; - -package internal; - -import "rule.proto"; - -message Type { - string name = 1; - string type = 2; - optional bool array = 3; - repeated Rule rules = 4; - optional Type parent = 5; -} \ No newline at end of file diff --git a/proto/actions/transfer.proto b/proto/actions/transfer.proto new file mode 100644 index 0000000..5021338 --- /dev/null +++ b/proto/actions/transfer.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +import "definitions.proto"; + +option ruby_package = "Tucana::Actions"; + +package actions; + +message InformationRequest { + string identifier = 1; + repeated shared.RuntimeFunctionDefinition function_definition = 2; + repeated shared.RuntimeParameterDefinition parameter_definition = 3; +} + +message InformationResponse { + bool success = 1; +} + +service ActionTransferService { + rpc Transfer (stream InformationRequest) returns (InformationResponse); +} \ No newline at end of file diff --git a/proto/internal/action.proto b/proto/internal/action.proto new file mode 100644 index 0000000..989b6a4 --- /dev/null +++ b/proto/internal/action.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; +import "definitions.proto"; + +option ruby_package = "Tucana::Internal"; + +package internal; + +message ActionLogonRequest { + string identifier = 1; + repeated shared.RuntimeFunctionDefinition function_definition = 2; + repeated shared.RuntimeParameterDefinition parameter_definition = 3; +} + +message ActionLogonResponse {} + +message ActionLogoffRequest { + string identifier = 1; +} + +message ActionLogoffResponse {} + +service ActionService { + rpc Logon (ActionLogonRequest) returns (ActionLogonResponse); + rpc Logoff (ActionLogoffRequest) returns (ActionLogoffResponse); +} \ No newline at end of file diff --git a/proto/internal/flow.proto b/proto/internal/flow.proto new file mode 100644 index 0000000..024c2be --- /dev/null +++ b/proto/internal/flow.proto @@ -0,0 +1,46 @@ +syntax = "proto3"; + +option ruby_package = "Tucana::Internal"; + +package internal; + +import "node.proto"; +import "flow_definition.proto"; + +message Flow { + Node start_node = 2; + FlowDefinition definition = 3; +} + +enum FlowCommandType { + INSERT = 0; + DELETE = 1; +} + +//Aquila sends a request to initialise stream to Sagittarius +message FlowLogonRequest { +} + +//Sagittarius sends flow to be updated +message FlowResponse { + Flow updated_flow = 1; + FlowCommandType type = 2; +} + +//All ids of flows that Aquila holds +message FlowGetRequest { + repeated int64 flow_ids = 1; +} + +//Sagittarius checks if he holds the flow_ids that Aquila sent +//If id is present --> sends flow +//If id is not present --> returns id to be deleted +message FlowGetResponse { + repeated Flow updated_flows = 1; + repeated int64 deleted_flow_ids = 2; +} + +service FlowService { + rpc Get (FlowGetRequest) returns (FlowGetResponse) {} + rpc Update (FlowLogonRequest) returns (stream FlowResponse) {} +} \ No newline at end of file diff --git a/internal/variable.proto b/proto/internal/flow_definition.proto similarity index 59% rename from internal/variable.proto rename to proto/internal/flow_definition.proto index e2867f0..a1af7fe 100644 --- a/internal/variable.proto +++ b/proto/internal/flow_definition.proto @@ -4,7 +4,5 @@ option ruby_package = "Tucana::Internal"; package internal; -message Variable { - string name = 1; - string type = 2; +message FlowDefinition { } \ No newline at end of file diff --git a/proto/internal/node.proto b/proto/internal/node.proto new file mode 100644 index 0000000..13d8af9 --- /dev/null +++ b/proto/internal/node.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +option ruby_package = "Tucana::Internal"; + +package internal; + +import "definitions.proto"; + +message Node { + shared.RuntimeFunctionDefinition definition = 1; + optional Node next_node = 2; + repeated Parameter parameters = 3; +} + +message Parameter { + shared.RuntimeParameterDefinition definition = 1; + optional string value = 2; + optional Node sub_node = 3; +} \ No newline at end of file diff --git a/internal/ping.proto b/proto/internal/ping.proto similarity index 100% rename from internal/ping.proto rename to proto/internal/ping.proto diff --git a/proto/shared/definitions.proto b/proto/shared/definitions.proto new file mode 100644 index 0000000..c056c1f --- /dev/null +++ b/proto/shared/definitions.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +option ruby_package = "Tucana::Shared"; + +package shared; + +message RuntimeFunctionDefinition { + string id = 1; +} + +message RuntimeParameterDefinition { + string name = 1; +} \ No newline at end of file