Class: AtlasRb::Resource

Inherits:
Object
  • Object
show all
Extended by:
FaradayHelper
Defined in:
lib/atlas_rb/resource.rb

Overview

Abstract base for every Atlas resource type.

Subclasses define a ROUTE constant (e.g. "/communities/") and override whichever of find / create / destroy / update / metadata / mods apply. The Resource class itself ships four endpoints that are not type-specific: a generic resolver, an XML preview helper, a permissions lookup, and an audit-event history fetch.

The Atlas resource hierarchy is:

{Community}  →  {Collection}  →  {Work}  →  {FileSet}  →  {Blob}

Subclasses extend FaradayHelper so that connection(...) and multipart(...) are available as class methods.

Direct Known Subclasses

Blob, Collection, Community, Delegate, FileSet, Work

Class Method Summary collapse

Methods included from FaradayHelper

connection, multipart, system_connection

Class Method Details

.find(id, nuid: nil, on_behalf_of: nil) ⇒ Hash{String => String, Hash}

Resolve any Atlas resource by ID without knowing its type up front.

The Atlas server returns a single-key JSON object whose key names the resource type ("community", "collection", "work", etc.); this method splits that into a normalized { "klass" => ..., "resource" => ... } pair so callers can dispatch on type.

Examples:

Polymorphic lookup

AtlasRb::Resource.find("abc123")
# => { "klass" => "Work", "resource" => { "id" => "abc123", "title" => "..." } }

Parameters:

  • id (String)

    an Atlas resource ID of any type.

  • nuid (String, nil) (defaults to: nil)

    optional acting user's NUID, forwarded as the User: header. Required for cerberus-token requests; legacy bearer tokens still resolve without it.

  • on_behalf_of (String, nil) (defaults to: nil)

    optional NUID for the On-Behalf-Of header. Falls through to AtlasRb.config.default_on_behalf_of when omitted.

Returns:

  • (Hash{String => String, Hash})

    hash with two keys:

    • "klass" — the resource type, capitalized (e.g. "Work").
    • "resource" — the resource payload as a Hash.


42
43
44
45
46
47
48
# File 'lib/atlas_rb/resource.rb', line 42

def self.find(id, nuid: nil, on_behalf_of: nil)
  result = JSON.parse(
    connection({}, nuid, on_behalf_of: on_behalf_of).get('/resources/' + id)&.body
  )
  AtlasRb::Mash.new("klass" => result.first[0].capitalize,
                    "resource" => result.first[1])
end

.history(id, nuid: nil, on_behalf_of: nil) ⇒ AtlasRb::Mash

TODO:

Add pagination support once Atlas's history endpoint exposes page / per_page query params. Today the endpoint returns the full history in one shot.

Fetch the audit-event history for a resource.

Wraps Atlas's GET /resources/<id>/history endpoint, which returns the full envelope (resource_id + reverse-chronological events array). The whole envelope is preserved so callers can confirm the events belong to the requested resource; access events as result["events"].

Authorization errors (401 / 403) are intentionally not caught here — they surface as raw Faraday responses for the calling application's rescue layer to translate.

Examples:

result = AtlasRb::Resource.history("abc12345")
result["resource_id"]            # => "abc12345"
result["events"].first["action"] # => "create"

Parameters:

  • id (String)

    an Atlas resource ID.

  • nuid (String, nil) (defaults to: nil)

    optional acting user's NUID, forwarded as the User: header. Required for cerberus-token requests; legacy bearer tokens still resolve without it.

  • on_behalf_of (String, nil) (defaults to: nil)

    optional NUID for the On-Behalf-Of header. Falls through to AtlasRb.config.default_on_behalf_of when omitted.

Returns:

  • (AtlasRb::Mash)

    the parsed envelope from GET /resources/<id>/history, with "resource_id" and an "events" array (reverse chronological; possibly empty).



125
126
127
128
129
130
# File 'lib/atlas_rb/resource.rb', line 125

def self.history(id, nuid: nil, on_behalf_of: nil)
  AtlasRb::Mash.new(JSON.parse(
    connection({}, nuid, on_behalf_of: on_behalf_of)
      .get('/resources/' + id + '/history')&.body
  ))
end

.permissions(id, nuid: nil, on_behalf_of: nil) ⇒ Hash

Fetch the access-control entries for a resource.

Examples:

AtlasRb::Resource.permissions("abc123")
# => { "id" => "abc123", "read" => [...], "write" => [...] }

Parameters:

  • id (String)

    an Atlas resource ID.

  • nuid (String, nil) (defaults to: nil)

    optional acting user's NUID, forwarded as the User: header. Required for cerberus-token requests; legacy bearer tokens still resolve without it.

  • on_behalf_of (String, nil) (defaults to: nil)

    optional NUID for the On-Behalf-Of header. Falls through to AtlasRb.config.default_on_behalf_of when omitted.

Returns:

  • (Hash)

    the "resource" payload from GET /resources/<id>/permissions, typically containing read/write/admin grant lists.



88
89
90
91
92
93
# File 'lib/atlas_rb/resource.rb', line 88

def self.permissions(id, nuid: nil, on_behalf_of: nil)
  AtlasRb::Mash.new(JSON.parse(
    connection({}, nuid, on_behalf_of: on_behalf_of)
      .get('/resources/' + id + '/permissions')&.body
  ))["resource"]
end

.preview(xml_path, nuid: nil, on_behalf_of: nil) ⇒ String

Validate a MODS XML document against Atlas's schema without persisting it.

Useful for surfacing validation errors in UIs before the user commits.

Examples:

AtlasRb::Resource.preview("/tmp/draft-mods.xml")

Parameters:

  • xml_path (String)

    path to a MODS XML file on disk.

  • nuid (String, nil) (defaults to: nil)

    optional acting user's NUID, forwarded as the User: header. Required for cerberus-token requests; legacy bearer tokens still resolve without it.

  • on_behalf_of (String, nil) (defaults to: nil)

    optional NUID for the On-Behalf-Of header. Falls through to AtlasRb.config.default_on_behalf_of when omitted.

Returns:

  • (String)

    the raw response body from POST /resources/preview — typically a JSON or XML error report.



66
67
68
69
70
71
# File 'lib/atlas_rb/resource.rb', line 66

def self.preview(xml_path, nuid: nil, on_behalf_of: nil)
  payload = { binary: Faraday::Multipart::FilePart.new(File.open(xml_path),
                                                       "application/xml",
                                                       File.basename(xml_path)) }
  multipart(nuid, on_behalf_of: on_behalf_of).post('/resources/preview', payload)&.body
end