Skip to content

Instantly share code, notes, and snippets.

@jackhong
Last active December 17, 2015 20:29
Show Gist options
  • Save jackhong/5668327 to your computer and use it in GitHub Desktop.
Save jackhong/5668327 to your computer and use it in GitHub Desktop.
class ResourceFactory
def self.create(res_type, res_options, creation_options, &callback)
# Find out Resource Module by resource type then:
#
# Initialise AbstractResource with provided resource parameters
AbstractResource.new(res_type, options, creation_options) do |resource|
# Then calling optional supplied callback
callback.call(resource)
end
end
end
class AbstractResource
def initialize(res_options, creation_options, &callback)
# We shall treat res_options as properties
#
# There are a limit number of core props (:uid, :hrn, :name) we need to initialise
# before creating/subscribing topic.
# Basically setting core props doesn't require communication and resource_address
#
# Initialise :uid, :hrn, :name via res_options
@uid = res_options.delete(:uid)
@name = res_options.delete(:name)
# What is left in res_options will be configured using API methods :configure_xxx,
# but only when/after subscribed to the topic (in case they will send inform msg voluntarily.
# Now we immediately create topic & subscribe to it
OmfCommon.comm.subscribe(@uid) do |topic|
begin
# Extend resource with Resource Module, can be obtained from Factory
#
# At this point we have everything we need to accept incoming msgs,
# send outgoing msgs
call_hook :before_ready, self
# Then can register certificates if provided.
# Then configure properties only using API methods.
# We shall rely on individual configure implementation for not blocking.
init_conifgure(res_options)
# Then send inform message to itself, with all res_options' current values.
# For consistency, only return properties values if API methods :request_xxx defined
inform(:creation_ok, res_values)
# Since we also passed parent in, we can send to parent here too.
parent.inform(:creation_ok, res_values) if parent
# Now we call additional callback passed in
callback.call(self)
rescue
# If error occurs, we shall inform CREATION_FAILED too, for bootstrap
inform(:creation_failed, res_values)
parent.inform(:creation_failed, res_values) if parent
end
end
end
# And now create child resource will be simplified
def create(res_type, res_options, creation_options, &callback)
call_hook(:before_create, self, res_type, res_options)
ResourceFactory.create(res_type, res_options, creation_options) do |new_resource|
# Adding resource to its children list
self.children << new_resource
call_hook(:after_create, self, new_resource)
# Might need to do sth addtional
callback.call(new_resource)
end
end
end
# Now for bootstrap
#
ResourceFactory.create(:node, { uid: 'node1', name: 'node1', membership: ['bob'] })
# Or supply additional block
ResourceFactory.create(:node,
{ uid: 'node1', name: 'node1', membership: ['bob'] },
{ suppress_create_message: false }) do |resource|
# Can optionally do additional things like, create some interfaces
resource.create(:net, { if_name: 'eth0', membership: ['alice'] })
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment