Skip to content

Commit

Permalink
Refactor async class to support kubernetes objects
Browse files Browse the repository at this point in the history
Splitting the Async class into 2 classes that inherit from the same base so
that we can type sniff later in code to determine which type of async
functionality should be used.
  • Loading branch information
chrisst committed Nov 19, 2019
1 parent c543128 commit 5b4bf68
Show file tree
Hide file tree
Showing 18 changed files with 420 additions and 374 deletions.
47 changes: 46 additions & 1 deletion api/async.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@
require 'api/timeout'

module Api
# Represents an asynchronous operation definition
# Base class from which other Async classes can inherit.
class Async < Api::Object
end

# Represents an asynchronous operation definition
class OpAsync < Async
attr_reader :operation
attr_reader :result
attr_reader :status
Expand Down Expand Up @@ -103,4 +107,45 @@ def validate
end
end
end

# Kubernetes shaped resources do not have a dedicated Operation that can be
# polled against for the resource's status. Instead the resource contains a
# status block which has conditions that represent the state of the resource.
# As of now there is a single product with only 2 resources that follow this
# convention, so following the 1,2,many rule this is a bare bones
# implementation until a larger pattern emerges.
class K8sAsync < Async
attr_reader :operation
# The list of methods where operations are used.
attr_reader :actions

def validate
super

check :operation, type: K8sAsync::Operation, required: true
check :actions, default: %w[create delete update], type: ::Array, item_type: ::String
end

def allow?(method)
@actions.include?(method.downcase)
end

# Since K8s like objects contain the status within the resource body this
# Operation class is just a light wrapper to call the resource itself
class Operation < Api::Object
attr_reader :base_url
attr_reader :full_url
attr_reader :timeouts

def validate
super

check :base_url, type: String
check :full_url, type: String
check :timeouts, type: Api::Timeouts

conflicts %i[base_url full_url]
end
end
end
end
3 changes: 2 additions & 1 deletion google/yaml_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ def check_type(name, object, type)
elsif type.is_a? ::Array
return if type.find_index(:boolean) && [TrueClass, FalseClass].find_index(object.class)
return unless type.find_index(object.class).nil?
elsif object.is_a?(type)
# check if class is or inherits from type
elsif object.class <= type
return
end
raise "Property '#{name}' is '#{object.class}' instead of '#{type}'"
Expand Down
10 changes: 5 additions & 5 deletions products/accesscontextmanager/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,21 @@ versions:
base_url: https://accesscontextmanager.googleapis.com/v1/
scopes:
- https://www.googleapis.com/auth/cloud-platform
async: !ruby/object:Api::Async
operation: !ruby/object:Api::Async::Operation
async: !ruby/object:Api::OpAsync
operation: !ruby/object:Api::OpAsync::Operation
path: 'name'
base_url: '{{op_id}}'
wait_ms: 1000
result: !ruby/object:Api::Async::Result
result: !ruby/object:Api::OpAsync::Result
path: 'response'
resource_inside_response: true
status: !ruby/object:Api::Async::Status
status: !ruby/object:Api::OpAsync::Status
path: 'done'
complete: true
allowed:
- true
- false
error: !ruby/object:Api::Async::Error
error: !ruby/object:Api::OpAsync::Error
path: 'error'
message: 'message'
objects:
Expand Down
30 changes: 15 additions & 15 deletions products/appengine/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,21 @@ objects:
'Official Documentation':
'https://cloud.google.com/appengine/docs/standard/python/mapping-custom-domains'
api: 'https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.domainMappings'
async: !ruby/object:Api::Async
operation: !ruby/object:Api::Async::Operation
async: !ruby/object:Api::OpAsync
operation: !ruby/object:Api::OpAsync::Operation
path: 'name'
base_url: '{{op_id}}'
wait_ms: 1000
result: !ruby/object:Api::Async::Result
result: !ruby/object:Api::OpAsync::Result
path: 'response'
resource_inside_response: true
status: !ruby/object:Api::Async::Status
status: !ruby/object:Api::OpAsync::Status
path: 'done'
complete: True
allowed:
- True
- False
error: !ruby/object:Api::Async::Error
error: !ruby/object:Api::OpAsync::Error
path: 'error'
message: 'message'
parameters:
Expand Down Expand Up @@ -226,22 +226,22 @@ objects:
'Official Documentation':
'https://cloud.google.com/appengine/docs/admin-api/deploying-overview'
api: 'https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.services.versions'
async: !ruby/object:Api::Async
operation: !ruby/object:Api::Async::Operation
async: !ruby/object:Api::OpAsync
operation: !ruby/object:Api::OpAsync::Operation
kind: 'appengine#operation'
path: 'name'
base_url: 'projects/{{project}}/global/operations/{{op_id}}'
wait_ms: 1000
result: !ruby/object:Api::Async::Result
result: !ruby/object:Api::OpAsync::Result
path: 'targetLink'
status: !ruby/object:Api::Async::Status
status: !ruby/object:Api::OpAsync::Status
path: 'status'
complete: 'DONE'
allowed:
- 'PENDING'
- 'RUNNING'
- 'DONE'
error: !ruby/object:Api::Async::Error
error: !ruby/object:Api::OpAsync::Error
path: 'error/errors'
message: 'message'
parameters:
Expand Down Expand Up @@ -472,21 +472,21 @@ objects:
update_verb: :PATCH
references: !ruby/object:Api::Resource::ReferenceLinks
api: 'https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps#UrlDispatchRule'
async: !ruby/object:Api::Async
operation: !ruby/object:Api::Async::Operation
async: !ruby/object:Api::OpAsync
operation: !ruby/object:Api::OpAsync::Operation
path: 'name'
base_url: '{{op_id}}'
wait_ms: 1000
result: !ruby/object:Api::Async::Result
result: !ruby/object:Api::OpAsync::Result
path: 'response'
status: !ruby/object:Api::Async::Status
status: !ruby/object:Api::OpAsync::Status
path: 'status'
complete: 'DONE'
allowed:
- 'PENDING'
- 'RUNNING'
- 'DONE'
error: !ruby/object:Api::Async::Error
error: !ruby/object:Api::OpAsync::Error
path: 'error/errors'
message: 'message'
properties:
Expand Down
10 changes: 5 additions & 5 deletions products/cloudfunctions/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,21 @@ objects:
A Cloud Function that contains user computation executed in response to an event.
collection_url_key: 'functions'
update_mask: true
async: !ruby/object:Api::Async
operation: !ruby/object:Api::Async::Operation
async: !ruby/object:Api::OpAsync
operation: !ruby/object:Api::OpAsync::Operation
path: 'name'
base_url: '{{op_id}}'
wait_ms: 1000
result: !ruby/object:Api::Async::Result
result: !ruby/object:Api::OpAsync::Result
path: 'response'
resource_inside_response: true
status: !ruby/object:Api::Async::Status
status: !ruby/object:Api::OpAsync::Status
path: 'done'
complete: True
allowed:
- True
- False
error: !ruby/object:Api::Async::Error
error: !ruby/object:Api::OpAsync::Error
path: 'error'
message: 'message'
parameters:
Expand Down
Loading

0 comments on commit 5b4bf68

Please sign in to comment.