Skip to content

Commit 08ad609

Browse files
committed
Added the first bit of Model Layer documentation and renamed the Contribution Guide placeholder.
1 parent d9dd428 commit 08ad609

5 files changed

Lines changed: 79 additions & 12 deletions

File tree

CHANGELOG.textile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
*2.2*
2+
* Added a method to reboot servers.
3+
14
*2.1.1*
25
* Virtual server upgrades no longer raise exceptions
36
* Formalized the RDoc documentation process. Added overview and welcome documentation and changed the README so it directs folks to the new documentation.
File renamed without changes.

doc_src/Model Layer.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# `softlayer_api` Model Layer
2+
3+
The Model Layer builds upon the Foundation layer and offers abstractions of the entities in the SoftLayer enviornment. For example, computing assets in the SoftLayer environment are found in two separate services [SoftLayer_Hardware](http://sldn.softlayer.com/reference/services/SoftLayer_Hardware) and [SoftLayer_Virtual_Guest](http://sldn.softlayer.com/reference/services/SoftLayer_Virtual_Guest). The Model Layer, however, creates a Server abstraction on top of those services. By doing so, a Ruby script can work with an instance of the SoftLayer::Server object class, send that object the "cancel!" message, and trust the underlying object framework to route the message to the appropriate service and routine within the network API.
4+
5+
The Model Layer is not meant to be complete. In fact, it models just a few key elements of the SoftLayer environment at this point, however we hope the Model Layer will grow and encompass more of the entities found in the API over time. In the interim, however, the current framework includes some convenient bridges that allow Ruby scripts to move from working with the abstractions of the Model Layer to the lower-level routines of the Foundation API easily.
6+
7+
The details of the individual classes that for the object class hierarchy of the Model layer are included in the API documentaiton. This document will discuss some of the general features of the Model Layer and the bridges that are in place to help code move between the Foundation and Model Layers.
8+
9+
# The ModelBase Class
10+
11+
The ModelBase is the abstract base class of object class hierarchy that forms the Model Layer of the `softlayer_api` Gem. An instance of ModelBase represents a single entity within the SoftLayer API.
12+
13+
In the Foundation layer, SoftLayer entities are represented as a Ruby hash whose keys and values are the are property names and property values of the entity. In the Model Layer, SoftLayer entities are represented by instances of the concrete subclasses of the Model Base class.
14+
15+
In implementation terms, an instance of the ModelBase class (or more accurately and instance of a concrete subclass of the ModelBase class) encapsulates the hashes of the Foundation layer defines the attributes and operations that form a convenient model for working with the underlying entity.
16+
17+
Here we will discuss the general features that all concrete subclasses of ModelBase share.
18+
19+
## Initializing Instances
20+
21+
The initializer for classes in the ModelBase hierarchy are declared:
22+
23+
def initialize(softlayer_client, network_hash)
24+
25+
end
26+
27+
The first argument is the client that the object may use to make requests to the network API. The second is the `network_hash`, the hash representation of the entity as returned by the network API.
28+
29+
The hash used to initialize an instance of ModelBase *must* contain a key, `id`, whose value is the `id` of the SoftLayer entity that the object model instance will represent. Correspondingly, the ModelBase class defines the `id` as having the same value as the `id` property in the network hash.
30+
31+
## Updating Instances from the Network
32+
33+
If you wish to ask an instance of ModelBase to update itself with the latest information from the SoftLayer network API, you may call the `refresh_details` method defined in the ModelBase class. This method is likely to make one or more calls through to the network API and will, consequently, incur the overhead of network communication. (Note: subclasses should not override `refresh_details` but should, instead, override the `softlayer_properties` method. Correspondingly, the softlayer_properties method is an implementation detail of ModelBase and is not intended to be called by outside code.)
34+
35+
## Bridging to the Foundation layer
36+
37+
Because the Model Layer offers limited coverage of the vast expanse of functionality found in the network API, it is often necessary to move from an object instance in the Model Layer to the implementation details from the Foundation layer. The Model Base class includes several features to help bridge the between layers gap.
38+
39+
### Accessing Properties
40+
41+
The ModelBase class defines the subscript operator (`[]`) to accept a property name as a string and return that property of the underlying hash. For example, given a ticket, represented by an instance of the SoftLayer::Ticket model layer class, there is no Model Layer representation corresponding to the `serviceProvider` property of the SoftLayer ticket entity. However, the subscript operator can be used to access that property from a model layer object:
42+
43+
ticket = SoftLayer::Ticket.ticket_with_id(123456)
44+
service_provider = ticket['serviceProvider']
45+
46+
In this case we ask the ticket for the value of the `serviceProvider` property. Note that the argument to the subscript operator is a string containing the property name.
47+
48+
This technique can only return values stored in the `softlayer_hash` encapsulated in the ModelBase class. Many classes in the Model Layer limit the information retrieved from the network (using object masks) to a subset of the full set of properties available through the network API. Scripts can check whether or not a given property is included in the underlying hash by calling the `has_sl_property?` method of ModelBase.
49+
50+
### Calling Network API routines
51+
52+
Where possible, each subclass of ModelBase should provide a `service` attribute. The value of that attribute should be an instance of SoftLayer::Service, with Service Helpers applied, suitable for addressing the SoftLayer entity represented by the object through the network API. For example, consider an instance of the Model Layer class SoftLayer::Ticket which represents a service ticket within the network API. The Ticket class defines the `service` attribute of that instance to be the value:
53+
54+
self.softlayer_client['Ticket'].object_with_id(self.id)
55+
56+
because this service object includes `object_with_id` service helper the result can be used to call through to the network API and that call will be directed at the SoftLayer_Ticket entity with the same id as the model object. For example:
57+
58+
ticket_object.service.getAttachedFile(file_id)
59+
60+
calls the `getAttachedFile` method of the SoftLayer_Ticket service which is not yet available in the SoftLayer::Ticket object model class.
61+
62+
## The rest of the model
63+
64+
The ModelBase class is literally the tip of the iceberg for the Model Layer, the bulk of functionality found in this layer is defined by concrete classes like SoftLayer::Ticket and SoftLayer::BareMetalServer, and in other abstract base classes like SoftLayer::Server. To understand the model presented by each class, we invite you to explore the API documentation.

lib/softlayer/ModelBase.rb

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -82,17 +82,6 @@ def refresh_details(object_mask = nil)
8282
@softlayer_hash = self.softlayer_properties(object_mask)
8383
end
8484

85-
##
86-
# Subclasses should implement this method as part of enabling the
87-
# refresh_details fuctionality The implementation should make a request
88-
# to the SoftLayer API and retrieve an up-to-date SoftLayer hash
89-
# representation of this object. That hash should be the return value
90-
# of this routine.
91-
#
92-
def softlayer_properties(object_mask = nil)
93-
raise "Abstract method softlayer_properties in ModelBase was called"
94-
end
95-
9685
##
9786
# Returns the value of of the given property as stored in the
9887
# softlayer_hash. This gives you access to the low-level, raw
@@ -132,6 +121,17 @@ def to_ary()
132121

133122
protected
134123

124+
##
125+
# Subclasses should implement this method as part of enabling the
126+
# refresh_details fuctionality The implementation should make a request
127+
# to the SoftLayer API and retrieve an up-to-date SoftLayer hash
128+
# representation of this object. That hash should be the return value
129+
# of this routine.
130+
#
131+
def softlayer_properties(object_mask = nil)
132+
raise "Abstract method softlayer_properties in ModelBase was called"
133+
end
134+
135135
##
136136
# The softlayer_hash stores the low-level information about an
137137
# object as it was retrieved from the SoftLayer API.

spec/object_mask_helpers_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484
end
8585

8686
describe Hash, "#to_sl_object_mask" do
87-
it "rejects the empty empty hash" do
87+
it "rejects the empty hash" do
8888
expect { {}.to_sl_object_mask }.to raise_error(RuntimeError)
8989
end
9090

0 commit comments

Comments
 (0)