diff --git a/README.md b/README.md index c1737621..6b99c814 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ Temporal.configure do |config| config.port = 7233 config.namespace = 'ruby-samples' config.task_queue = 'hello-world' + config.channel_creds = :this_channel_is_insecure end ``` @@ -103,6 +104,24 @@ activities. To set it up locally, download and boot the Docker Compose file from > docker-compose up ``` +### Connecting via SSL + +In many production deployments you will end up connecting to your Temporal Services via SSL. In which +case you must read the public cert of the CA that issued your Temporal server's SSL cert and create +an instance of GRPC Channel Credentials. + +Configure your Temporal connection: + +```ruby +Temporal.configure do |config| + config.host = 'temporal-prod.mycompany.com' + config.port = 7233 + config.namespace = 'ruby-samples' + config.task_queue = 'hello-world' + config.channel_creds = GRPC::Core::ChannelCredentials.new(CA_CERT) +end +``` + ## Workflows A workflow is defined using pure Ruby code, however it should contain only a high-level diff --git a/lib/temporal/client.rb b/lib/temporal/client.rb index 2c9952ea..d1ff4719 100644 --- a/lib/temporal/client.rb +++ b/lib/temporal/client.rb @@ -15,7 +15,11 @@ def self.generate thread_id = Thread.current.object_id identity = "#{thread_id}@#{hostname}" - client_class.new(host, port, identity) + if Temporal.configuration.client_type == :grpc + client_class.new(host, port, identity, Temporal.configuration.grpc_ssl_config) + else + client_class.new(host, port, identity) + end end end end diff --git a/lib/temporal/client/grpc_client.rb b/lib/temporal/client/grpc_client.rb index 4a295db6..6ef4710a 100644 --- a/lib/temporal/client/grpc_client.rb +++ b/lib/temporal/client/grpc_client.rb @@ -22,9 +22,10 @@ class GRPCClient close: Temporal::Api::Enums::V1::HistoryEventFilterType::HISTORY_EVENT_FILTER_TYPE_CLOSE_EVENT, }.freeze - def initialize(host, port, identity) + def initialize(host, port, identity, grpc_ssl_config) @url = "#{host}:#{port}" @identity = identity + @channel_creds = grpc_ssl_config @poll = true @poll_mutex = Mutex.new @poll_request = nil @@ -388,12 +389,12 @@ def cancel_polling_request private - attr_reader :url, :identity, :poll_mutex, :poll_request + attr_reader :url, :channel_creds, :identity, :poll_mutex, :poll_request def client @client ||= Temporal::Api::WorkflowService::V1::WorkflowService::Stub.new( url, - :this_channel_is_insecure, + channel_creds, timeout: 60 ) end diff --git a/lib/temporal/configuration.rb b/lib/temporal/configuration.rb index f6e59fa2..c1cf8404 100644 --- a/lib/temporal/configuration.rb +++ b/lib/temporal/configuration.rb @@ -4,7 +4,7 @@ module Temporal class Configuration attr_reader :timeouts, :error_handlers - attr_accessor :client_type, :host, :port, :logger, :metrics_adapter, :namespace, :task_queue, :headers + attr_accessor :channel_creds, :client_type, :host, :port, :logger, :metrics_adapter, :namespace, :task_queue, :headers # We want an infinite execution timeout for cron schedules and other perpetual workflows. # We choose an 10-year execution timeout because that's the maximum the cassandra DB supports, @@ -32,6 +32,7 @@ def initialize @namespace = DEFAULT_NAMESPACE @task_queue = DEFAULT_TASK_QUEUE @headers = DEFAULT_HEADERS + @channel_creds = nil @error_handlers = [] end @@ -50,5 +51,13 @@ def task_list=(name) def timeouts=(new_timeouts) @timeouts = DEFAULT_TIMEOUTS.merge(new_timeouts) end + + def grpc_ssl_config + if @channel_creds.nil? + :this_channel_is_insecure + else + @channel_creds + end + end end end diff --git a/spec/unit/lib/temporal/grpc_client_spec.rb b/spec/unit/lib/temporal/grpc_client_spec.rb index 1f1b0118..566f1a33 100644 --- a/spec/unit/lib/temporal/grpc_client_spec.rb +++ b/spec/unit/lib/temporal/grpc_client_spec.rb @@ -1,5 +1,5 @@ describe Temporal::Client::GRPCClient do - subject { Temporal::Client::GRPCClient.new(nil, nil, nil) } + subject { Temporal::Client::GRPCClient.new(nil, nil, nil, :this_channel_is_insecure) } let(:grpc_stub) { double('grpc stub') } let(:namespace) { 'test-namespace' } let(:workflow_id) { SecureRandom.uuid }