Class: EsuApi::EsuRestApi
- Inherits:
-
Object
- Object
- EsuApi::EsuRestApi
- Defined in:
- lib/EsuApi.rb
Overview
The EsuRestApi object creates a connection to the Atmos REST API
Note that this class is not thread-safe. Each instance maps one-to-one to a Net::HTTP session. Therefore, each instance must be kept in a thread local or pooled using something like common-pool: www.pluitsolutions.com/projects/common-pool
Constant Summary collapse
- GET =
"GET"
- POST =
"POST"
- PUT =
"PUT"
- DELETE =
"DELETE"
- HEAD =
"HEAD"
- ID_EXTRACTOR =
/\/[0-9a-zA-Z]+\/objects\/([0-9a-f]{44})/
- OID_TEST =
/^[0-9a-f]{44}$/
- PATH_TEST =
/^\/.*/
Instance Method Summary collapse
-
#create_object(acl, metadata, data, mimetype, hash = nil) ⇒ Object
Creates a new object in Atmos and returns its Object ID.
-
#create_object_on_path(path, acl, metadata, data, mimetype, hash = nil) ⇒ Object
Creates an object on the given path.
-
#delete_object(id) ⇒ Object
Deletes an object.
-
#delete_user_metadata(id, tags) ⇒ Object
Deletes user metadata from an object.
-
#delete_version(vid) ⇒ Object
Deletes an object version.
-
#get_acl(id) ⇒ Object
Gets an object’s ACL.
-
#get_listable_tags(tag_root = nil) ⇒ Object
Returns the listable tags present in the system.
-
#get_object_metadata(id) ⇒ Object
Fetches the user metadata, system metadata, mimetype, and ACL for an object.
-
#get_service_information ⇒ Object
Returns a #ServiceInformation object containing the version of Atmos the client is connected to.
-
#get_shareable_url(id, expires) ⇒ Object
Generates a pre-signed URL to read an object that can be shared with external users or systems.
-
#get_system_metadata(id, tags = nil) ⇒ Object
Gets the system metadata on an object.
-
#get_user_metadata(id, tags = nil) ⇒ Object
Gets the user metadata on an object.
-
#initialize(host, port, uid, secret) ⇒ EsuRestApi
constructor
Creates a new connection.
-
#list_directory(dir) ⇒ Object
Lists the contents of a directory.
-
#list_objects(tag) ⇒ Object
Lists the objects tagged with the given listable metadata tag.
-
#list_objects_with_metadata(tag) ⇒ Object
Lists the objects tagged with the given listable metadata tag.
-
#list_user_metadata_tags(id) ⇒ Object
Gets the list of user metadatda tags on an object.
-
#list_versions(id) ⇒ Object
Lists the versions of an object.
-
#read_object(id, extent, checksum = nil) ⇒ Object
Reads an object’s content.
-
#rename(source, destination, overwrite = false) ⇒ Object
Renames an object in the namespace.
-
#restore_version(id, vid) ⇒ Object
Restores (“promotes”) a version to the base object content, i.e.
-
#update_object(id, acl, metadata, data, extent, mimetype, hash = nil) ⇒ Object
Updates an object in Atmos.
-
#version_object(id) ⇒ Object
Creates a new version of an object.
Constructor Details
#initialize(host, port, uid, secret) ⇒ EsuRestApi
Creates a new connection
-
host - the access point host
-
port - the port to connect with
-
uid - the Atmos UID
-
secret - the base64-encoded secret key for the UID
60 61 62 63 64 65 66 67 68 |
# File 'lib/EsuApi.rb', line 60 def initialize( host, port, uid, secret ) @host = host @port = port @uid = uid @secret = Base64.decode64( secret ) @session = Net::HTTP.new( host, port ).start @context = "/rest" end |
Instance Method Details
#create_object(acl, metadata, data, mimetype, hash = nil) ⇒ Object
Creates a new object in Atmos and returns its Object ID
-
acl - the ACL to apply to the object. May be nil.
-
metadata - the object’s initial metadata as a hash of name => Metadata,
may be nil.
-
data - data for the object. If nil, a zero-length object will be
created.
-
mimetype - the object’s mimetype. If not specified, will default
to application/octet-stream.
-
hash - optional. If specified, the object will be populated with
the hash of the data passed. If uploading a file in multiple chunks, the same hash object should be passed to the subsequent update calls.
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/EsuApi.rb', line 82 def create_object( acl, , data, mimetype, hash = nil) uri = URI::HTTP.build( {:host => @host, :port => @port, :path => @context + "/objects" } ) headers = {} if( data == nil ) data = "" end headers["content-length"] = String(data.length()) if( acl ) process_acl( acl, headers ) end if( ) ( , headers ) end if( hash ) update_hash( hash, data, headers ) end request = build_request( EsuRestApi::POST, uri, headers, mimetype ) request.body = data response = @session.request( request ) handle_error( response ) return ID_EXTRACTOR.match( response["location"] )[1].to_s end |
#create_object_on_path(path, acl, metadata, data, mimetype, hash = nil) ⇒ Object
Creates an object on the given path. The path must start with a slash (/) character. When complete, returns the ID of the new object.
-
path - the path in the namespace, e.g. “/myfile.txt”
-
acl - the ACL to apply to the object. May be nil. Should be an
#Array of #Grant objects
-
metadata - the object’s initial metadata as a hash of name => Metadata,
may be nil.
-
data - data for the object. If nil, a zero-length object will be
created.
-
mimetype - the object’s mimetype. If not specified, will default
to application/octet-stream.
-
hash - optional. If specified, the object will be populated with
the hash of the data passed. If uploading a file in multiple chunks, the same hash object should be passed to the subsequent update calls.
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/EsuApi.rb', line 130 def create_object_on_path( path, acl, , data, mimetype, hash = nil) uri = URI::HTTP.build( {:host => @host, :port => @port, :path => build_resource( path ) } ) headers = {} if( data == nil ) data = "" end headers["content-length"] = String(data.length()) if( acl ) process_acl( acl, headers ) end if( ) ( , headers ) end if( hash ) update_hash( hash, data, headers ) end request = build_request( EsuRestApi::POST, uri, headers, mimetype ) request.body = data response = @session.request( request ) handle_error( response ) return ID_EXTRACTOR.match( response["location"] )[1].to_s end |
#delete_object(id) ⇒ Object
Deletes an object.
-
id - A string containing either an Object ID or a path
166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/EsuApi.rb', line 166 def delete_object( id ) uri = URI::HTTP.build( {:host => @host, :port => @port, :path => build_resource(id) } ) headers = {} request = build_request( EsuRestApi::DELETE, uri, headers, nil ) response = @session.request( request ) handle_error( response ) end |
#delete_user_metadata(id, tags) ⇒ Object
Deletes user metadata from an object
-
id - a String containing an object ID or an object path
-
tags - an Array containing the names of the user metadata elements
to delete from the object.
352 353 354 355 356 357 358 359 360 361 362 363 364 |
# File 'lib/EsuApi.rb', line 352 def ( id, ) uri = URI::HTTP.build( {:host => @host, :port => @port, :path => build_resource(id), :query => "metadata/user" } ) headers = {} headers["x-emc-tags"] = .join( "," ) request = build_request( EsuRestApi::DELETE, uri, headers, nil ) response = @session.request( request ) handle_error( response ) end |
#delete_version(vid) ⇒ Object
Deletes an object version. Note that you’ll get an access error if you pass a version ID to #delete_object
-
vid - a String containing an object version ID
390 391 392 393 394 395 396 397 398 399 400 401 |
# File 'lib/EsuApi.rb', line 390 def delete_version( vid ) uri = URI::HTTP.build( {:host => @host, :port => @port, :path => build_resource(vid), :query => "versions" } ) headers = {} request = build_request( EsuRestApi::DELETE, uri, headers, nil ) response = @session.request( request ) handle_error( response ) end |
#get_acl(id) ⇒ Object
Gets an object’s ACL. Returns an #Array containing #Grant objects.
-
id - a #String containing either an object ID or an object path
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 |
# File 'lib/EsuApi.rb', line 269 def get_acl( id ) uri = URI::HTTP.build( {:host => @host, :port => @port, :path => build_resource(id), :query => "acl" } ) headers = {} request = build_request( EsuRestApi::GET, uri, headers, nil ) response = @session.request( request ) handle_error( response ) # Parse returned ACLs acl = [] parse_acl( acl, response["x-emc-groupacl"], EsuApi::Grantee::GROUP ) parse_acl( acl, response["x-emc-useracl"], EsuApi::Grantee::USER ) return acl end |
#get_listable_tags(tag_root = nil) ⇒ Object
Returns the listable tags present in the system.
-
tag_root - Optional. If specified, only the listable tags under
the root are returned. If omitted, the root tags will be returned.
488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 |
# File 'lib/EsuApi.rb', line 488 def ( tag_root = nil ) uri = URI::HTTP.build( {:host => @host, :port => @port, :path => @context + "/objects", :query => "listabletags" } ) headers = {} if( tag_root != nil ) headers["x-emc-tags"] = tag_root end request = build_request( EsuRestApi::GET, uri, headers, nil ) response = @session.request( request ) handle_error( response ) return ( response ) end |
#get_object_metadata(id) ⇒ Object
Fetches the user metadata, system metadata, mimetype, and ACL for an object. Returned as a hash with the key symbols:
-
:meta
-
:acl
-
:mimetype
-
id - A String containing an object ID or object path
452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 |
# File 'lib/EsuApi.rb', line 452 def ( id ) uri = URI::HTTP.build( {:host => @host, :port => @port, :path => build_resource(id) }) headers = {} request = build_request( EsuRestApi::HEAD, uri, headers, nil ) response = @session.request( request ) handle_error( response ) # Parse returned metadata om = {} = {} ( , response["x-emc-meta"], false ) ( , response["x-emc-listable-meta"], true ) om[:meta] = # Parse returned ACLs acl = [] parse_acl( acl, response["x-emc-groupacl"], EsuApi::Grantee::GROUP ) parse_acl( acl, response["x-emc-useracl"], EsuApi::Grantee::USER ) om[:acl] = acl # Get mimetype om[:mimetype] = response["content-type"] return om end |
#get_service_information ⇒ Object
Returns a #ServiceInformation object containing the version of Atmos the client is connected to.
509 510 511 512 513 514 515 516 517 518 519 520 521 522 |
# File 'lib/EsuApi.rb', line 509 def get_service_information() uri = URI::HTTP.build( {:host => @host, :port => @port, :path => @context + "/service"} ) headers = {} request = build_request( EsuRestApi::GET, uri, headers, nil ) response = @session.request( request ) handle_error( response ) return parse_service_information( response ) end |
#get_shareable_url(id, expires) ⇒ Object
Generates a pre-signed URL to read an object that can be shared with external users or systems.
-
id - a String containing an object ID or object path
-
expires - a #Time object containing the expiration date and time in UTC
529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 |
# File 'lib/EsuApi.rb', line 529 def get_shareable_url( id, expires ) uri = URI::HTTP.build( {:host => @host, :port => @port, :path => build_resource(id) }) sb = "GET\n" sb += uri.path.downcase+ "\n" sb += @uid + "\n" sb += String(expires.to_i()) signature = sign( sb ) uri.query = "uid=#{CGI::escape(@uid)}&expires=#{expires.to_i()}&signature=#{CGI::escape(signature)}" return uri end |
#get_system_metadata(id, tags = nil) ⇒ Object
Gets the system metadata on an object. Returns a #Hash of metadata name => #Metadata objects, e.g. ctime, atime, mtime, size
-
id - a String containing either an object ID or an object path
-
tags - Optional. If specified, an Array of Strings containing the
system metadata tags to fetch from the server.
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 |
# File 'lib/EsuApi.rb', line 325 def ( id, = nil ) uri = URI::HTTP.build( {:host => @host, :port => @port, :path => build_resource(id), :query => "metadata/system" } ) headers = {} if( != nil ) ( , headers ) end request = build_request( EsuRestApi::GET, uri, headers, nil ) response = @session.request( request ) handle_error( response ) # Parse returned metadata = {} ( , response["x-emc-meta"], false ) return end |
#get_user_metadata(id, tags = nil) ⇒ Object
Gets the user metadata on an object. Returns a #Hash of metadata name => #Metadata objects.
-
id - a String containing either an object ID or an object path
-
tags - Optional. If specified, an Array of Strings containing the
user metadata tags to fetch from the server.
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
# File 'lib/EsuApi.rb', line 296 def ( id, = nil ) uri = URI::HTTP.build( {:host => @host, :port => @port, :path => build_resource(id), :query => "metadata/user" } ) headers = {} if( != nil ) ( , headers ) end request = build_request( EsuRestApi::GET, uri, headers, nil ) response = @session.request( request ) handle_error( response ) # Parse returned metadata = {} ( , response["x-emc-meta"], false ) ( , response["x-emc-listable-meta"], true ) return end |
#list_directory(dir) ⇒ Object
Lists the contents of a directory. Returns an Array of #DirectoryEntry objects.
-
dir - a String containing a directory path. Note that directory paths
must end with a slash (‘/’) character.
550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 |
# File 'lib/EsuApi.rb', line 550 def list_directory( dir ) if !/^\/.*\/$/.match( dir ) throw "Invalid directory '#{dir}'. Directories must start and end with a slash (/)" end uri = URI::HTTP.build( {:host => @host, :port => @port, :path => build_resource(dir) } ) headers = {} request = build_request( EsuRestApi::GET, uri, headers, nil ) response = @session.request( request ) handle_error( response ) return parse_directory( response, dir ) end |
#list_objects(tag) ⇒ Object
Lists the objects tagged with the given listable metadata tag. Returns an Array of object IDs.
-
tag - the tag whose contents to list.
573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 |
# File 'lib/EsuApi.rb', line 573 def list_objects( tag ) uri = URI::HTTP.build( {:host => @host, :port => @port, :path => @context + "/objects" } ) headers = {} headers["x-emc-tags"] = tag request = build_request( EsuRestApi::GET, uri, headers, nil ) response = @session.request( request ) handle_error( response ) return parse_object_list( response ) end |
#list_objects_with_metadata(tag) ⇒ Object
Lists the objects tagged with the given listable metadata tag. Returns a Hash of object ID => #ObjectMetadata elements
-
tag - the tag whose contents to list
593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 |
# File 'lib/EsuApi.rb', line 593 def ( tag ) uri = URI::HTTP.build( {:host => @host, :port => @port, :path => @context + "/objects" } ) headers = {} headers["x-emc-tags"] = tag headers["x-emc-include-meta"] = "1" request = build_request( EsuRestApi::GET, uri, headers, nil ) response = @session.request( request ) handle_error( response ) return ( response ) end |
#list_user_metadata_tags(id) ⇒ Object
Gets the list of user metadatda tags on an object
-
id - a String containing the object ID or object path
614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 |
# File 'lib/EsuApi.rb', line 614 def ( id ) uri = URI::HTTP.build( {:host => @host, :port => @port, :path => build_resource(id), :query => "metadata/tags" } ) headers = {} request = build_request( EsuRestApi::GET, uri, headers, nil ) response = @session.request( request ) handle_error( response ) # Parse returned metadata = [] parse_tag_list( , response["x-emc-tags"] ) parse_tag_list( , response["x-emc-listable-tags"] ) return end |
#list_versions(id) ⇒ Object
Lists the versions of an object. Returns an Array of Strings containing the object version IDs.
-
id - a String containing the object ID or object path of the base
object
429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 |
# File 'lib/EsuApi.rb', line 429 def list_versions(id) uri = URI::HTTP.build( {:host => @host, :port => @port, :path => build_resource(id), :query => "versions" } ) headers = {} request = build_request( EsuRestApi::GET, uri, headers, nil ) response = @session.request( request ) handle_error( response ) # Parse returned IDs return parse_version_list( response ) end |
#read_object(id, extent, checksum = nil) ⇒ Object
Reads an object’s content.
-
id - A string containing either an Object ID or an object path.
-
extent - If nil, the entire object will be returned. Otherwise, only
the requested extent will be returned
-
checksum - Optional. If specified, the data will be added to the
given checksum object. Note that Atmos currently only supports read checksums on erasure coded objects. If you’re reading a file in sequential chunks, pass the same checksum object to each request. When complete, check the checksum object’s expected_value against it’s to_s() value.
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/EsuApi.rb', line 190 def read_object( id, extent, checksum = nil ) uri = URI::HTTP.build( {:host => @host, :port => @port, :path => build_resource(id) } ) headers = {} if( extent != nil ) headers["range"] = "#{extent}" end request = build_request( EsuRestApi::GET, uri, headers, nil ) response = @session.request( request ) handle_error( response ) if( checksum != nil ) checksum.update( response.body ) if( response["x-emc-wschecksum"] != nil ) checksum.expected_value = response["x-emc-wschecksum"] end end return response.body end |
#rename(source, destination, overwrite = false) ⇒ Object
Renames an object in the namespace
-
source - the path of the source object
-
destination - the path of the destination object
-
overwrite - if true, the destination will be overwritten if it exists.
If false, the operation will fail if the destination exists. Note that overwriting an object is asynchronous; it may take a few seconds for the destination object to be replaced.
642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 |
# File 'lib/EsuApi.rb', line 642 def rename( source, destination, overwrite = false ) uri = URI::HTTP.build( {:host => @host, :port => @port, :path => build_resource(source), :query => "rename" } ) headers = {} headers["x-emc-path"] = destination if( overwrite ) headers["x-emc-force"] = "#{overwrite}" end request = build_request( EsuRestApi::POST, uri, headers, nil ) response = @session.request( request ) handle_error( response ) end |
#restore_version(id, vid) ⇒ Object
Restores (“promotes”) a version to the base object content, i.e. the object’s content will be replaced with the contents of the version.
-
id - a String containing the object ID or object path of the base
object
-
vid - a String containing the object version ID to replace the base
content with
410 411 412 413 414 415 416 417 418 419 420 421 422 |
# File 'lib/EsuApi.rb', line 410 def restore_version( id, vid ) uri = URI::HTTP.build( {:host => @host, :port => @port, :path => build_resource(id), :query => "versions" } ) headers = {} headers["x-emc-version-oid"] = vid request = build_request( EsuRestApi::PUT, uri, headers, nil ) response = @session.request( request ) handle_error( response ) end |
#update_object(id, acl, metadata, data, extent, mimetype, hash = nil) ⇒ Object
Updates an object in Atmos
-
id - a String containing either an object ID or an object path.
-
acl - the ACL to apply to the object. May be nil. Should be an
#Array of #Grant objects
-
metadata - the object’s initial metadata as a hash of name => Metadata,
may be nil.
-
data - data for the object. If nil, a zero-length object will be
created.
-
mimetype - the object’s mimetype. If not specified, will default
to application/octet-stream.
-
hash - optional. If specified, the object will be populated with
the hash of the data passed. If uploading a file in multiple chunks, the same hash object should be passed to the subsequent update calls.
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
# File 'lib/EsuApi.rb', line 231 def update_object( id, acl, , data, extent, mimetype, hash = nil) uri = URI::HTTP.build( {:host => @host, :port => @port, :path => build_resource(id) } ) headers = {} if( data == nil ) data = "" end headers["content-length"] = String(data.length()) if( extent != nil ) headers["range"] = "${extent}" end if( acl ) process_acl( acl, headers ) end if( ) ( , headers ) end if( hash ) update_hash( hash, data, headers ) end request = build_request( EsuRestApi::PUT, uri, headers, mimetype ) request.body = data response = @session.request( request ) handle_error( response ) end |
#version_object(id) ⇒ Object
Creates a new version of an object. Returns the ID of the new version. Note that versions are immutable. See #restore_version.
-
id - a String containing an object ID or an object path.
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 |
# File 'lib/EsuApi.rb', line 370 def version_object( id ) uri = URI::HTTP.build( {:host => @host, :port => @port, :path => build_resource(id), :query => "versions" } ) headers = {} request = build_request( EsuRestApi::POST, uri, headers, nil ) response = @session.request( request ) handle_error( response ) # Parse returned ID return ID_EXTRACTOR.match( response["location"] )[1].to_s end |