Skip to content

Commit

Permalink
Merge pull request #446 from datacite/provider-client-activities
Browse files Browse the repository at this point in the history
track changes for providers and clients
  • Loading branch information
Martin Fenner authored Mar 6, 2020
2 parents e70c3d4 + 812b9bf commit 4c5f5ed
Show file tree
Hide file tree
Showing 11 changed files with 143 additions and 185 deletions.
16 changes: 5 additions & 11 deletions app/controllers/activities_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ class ActivitiesController < ApplicationController
include Countable

before_action :set_activity, only: [:show]
before_action :set_include

def index
sort = case params[:sort]
Expand All @@ -19,7 +18,11 @@ def index
elsif params[:ids].present?
response = Activity.find_by_id(params[:ids], page: page, sort: sort)
else
response = Activity.query(params[:query], uid: params[:doi_id], page: page, sort: sort, scroll_id: params[:scroll_id])
response = Activity.query(params[:query],
uid: params[:doi_id] || params[:provider_id] || params[:client_id] || params[:repository_id],
page: page,
sort: sort,
scroll_id: params[:scroll_id])
end

begin
Expand Down Expand Up @@ -91,15 +94,6 @@ def show

protected

def set_include
if params[:include].present?
@include = params[:include].split(",").map { |i| i.downcase.underscore.to_sym }
@include = @include & [:doi]
else
@include = [:doi]
end
end

def set_activity
response = Activity.find_by_id(params[:id])
@activity = response.results.first
Expand Down
177 changes: 33 additions & 144 deletions app/models/activity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class Activity < Audited::Audit
alias_attribute :doi_id, :uid
alias_attribute :changes, :audited_changes

belongs_to :doi, foreign_key: :auditable_id
belongs_to :auditable, polymorphic: true

def after_audit
IndexJob.perform_later(self)
Expand All @@ -20,170 +20,34 @@ def after_audit
mapping dynamic: 'false' do
indexes :id, type: :keyword
indexes :auditable_id, type: :keyword
indexes :doi_id, type: :keyword
indexes :uid, type: :keyword
indexes :auditable_type, type: :keyword
indexes :username, type: :keyword
indexes :action, type: :keyword
indexes :version, type: :keyword
indexes :request_uuid, type: :keyword
indexes :changes, type: :object, properties: {
doi: { type: :keyword },
url: { type: :text, fields: { keyword: { type: "keyword" }}},
creators: { type: :object, properties: {
nameType: { type: :keyword },
nameIdentifiers: { type: :object, properties: {
nameIdentifier: { type: :keyword },
nameIdentifierScheme: { type: :keyword },
schemeUri: { type: :keyword }
}},
name: { type: :text },
givenName: { type: :text },
familyName: { type: :text },
affiliation: { type: :object, properties: {
name: { type: :keyword },
affiliationIdentifier: { type: :keyword },
affiliationIdentifierScheme: { type: :keyword },
schemeUri: { type: :keyword }
}},
}},
contributors: { type: :object, properties: {
nameType: { type: :keyword },
nameIdentifiers: { type: :object, properties: {
nameIdentifier: { type: :keyword },
nameIdentifierScheme: { type: :keyword },
schemeUri: { type: :keyword }
}},
name: { type: :text },
givenName: { type: :text },
familyName: { type: :text },
affiliation: { type: :object, properties: {
name: { type: :keyword },
affiliationIdentifier: { type: :keyword },
affiliationIdentifierScheme: { type: :keyword },
schemeUri: { type: :keyword }
}},
contributorType: { type: :keyword }
}},
titles: { type: :object, properties: {
title: { type: :text, fields: { keyword: { type: "keyword" }}},
titleType: { type: :keyword },
lang: { type: :keyword }
}},
descriptions: { type: :object, properties: {
description: { type: :text },
descriptionType: { type: :keyword },
lang: { type: :keyword }
}},
publisher: { type: :text, fields: { keyword: { type: "keyword" }}},
publication_year: { type: :date, format: "yyyy", ignore_malformed: true },
client_id: { type: :keyword },
provider_id: { type: :keyword },
identifiers: { type: :object, properties: {
identifierType: { type: :keyword },
identifier: { type: :keyword }
}},
related_identifiers: { type: :object, properties: {
relatedIdentifierType: { type: :keyword },
relatedIdentifier: { type: :keyword },
relationType: { type: :keyword },
relatedMetadataScheme: { type: :keyword },
schemeUri: { type: :keyword },
schemeType: { type: :keyword },
resourceTypeGeneral: { type: :keyword }
}},
types: { type: :object, properties: {
resourceTypeGeneral: { type: :keyword },
resourceType: { type: :keyword },
schemaOrg: { type: :keyword },
bibtex: { type: :keyword },
citeproc: { type: :keyword },
ris: { type: :keyword }
}},
funding_references: { type: :object, properties: {
funderName: { type: :keyword },
funderIdentifier: { type: :keyword },
funderIdentifierType: { type: :keyword },
awardNumber: { type: :keyword },
awardUri: { type: :keyword },
awardTitle: { type: :keyword }
}},
dates: { type: :object, properties: {
date: { type: :text },
dateType: { type: :keyword }
}},
geo_locations: { type: :object, properties: {
geoLocationPoint: { type: :object },
geoLocationBox: { type: :object },
geoLocationPlace: { type: :keyword }
}},
rights_list: { type: :object, properties: {
rights: { type: :keyword },
rightsUri: { type: :keyword },
lang: { type: :keyword },
}},
subjects: { type: :object, properties: {
subject: { type: :keyword },
subjectScheme: { type: :keyword },
schemeUri: { type: :keyword },
valueUri: { type: :keyword },
lang: { type: :keyword },
}},
container: { type: :object, properties: {
type: { type: :keyword },
identifier: { type: :keyword },
identifierType: { type: :keyword },
title: { type: :keyword },
volume: { type: :keyword },
issue: { type: :keyword },
firstPage: { type: :keyword },
lastPage: { type: :keyword },
}},
content_url: { type: :keyword },
version_info: { type: :keyword },
formats: { type: :keyword },
sizes: { type: :keyword },
language: { type: :keyword },
aasm_state: { type: :keyword },
schema_version: { type: :keyword },
metadata_version: { type: :keyword },
source: { type: :keyword },
landing_page: { type: :object, properties: {
checked: { type: :date, ignore_malformed: true },
url: { type: :text, fields: { keyword: { type: "keyword" }}},
status: { type: :integer },
contentType: { type: :keyword },
error: { type: :keyword },
redirectCount: { type: :integer },
redirectUrls: { type: :keyword },
downloadLatency: { type: :scaled_float, scaling_factor: 100 },
hasSchemaOrg: { type: :boolean },
schemaOrgId: { type: :keyword },
dcIdentifier: { type: :keyword },
citationDoi: { type: :keyword },
bodyHasPid: { type: :boolean }
}}
}
indexes :changes, type: :object
indexes :created, type: :date, ignore_malformed: true

# include parent objects
indexes :doi, type: :object
#indexes :doi, type: :object
end

def as_indexed_json(options={})
{
"id" => id,
"auditable_id" => auditable_id,
"doi_id" => doi_id,
"uid" => uid,
"auditable_type" => auditable_type,
"username" => username,
"action" => action,
"version" => version,
"request_uuid" => request_uuid,
"changes" => changes,
"created" => created,
"doi" => doi.present? ? doi.as_indexed_json : nil
"was_derived_from" => was_derived_from,
"was_attributed_to" => was_attributed_to,
"was_generated_by" => was_generated_by,
"created" => created
}
end

Expand Down Expand Up @@ -322,6 +186,31 @@ def self.convert_affiliation_by_id(options={})
end

def uid
doi.present? ? doi.uid : changes.to_h['doi']
auditable.uid
end

def url
Rails.env.production? ? "https://api.datacite.org" : "https://api.test.datacite.org"
end

def was_derived_from
if auditable_type == "Doi"
handle_url = Rails.env.production? ? "https://doi.org/" : "https://handle.test.datacite.org/"
handle_url + uid
elsif auditable_type == "Provider"
url + "/providers/" + uid
elsif auditable_type == "Client"
url + "/repositories/" + uid
end
end

def was_attributed_to
if username.present?
username.include?(".") ? url + "/repositories/" + username : url + "/providers/" + username
end
end

def was_generated_by
url + "/activities/" + request_uuid
end
end
2 changes: 2 additions & 0 deletions app/models/client.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
class Client < ActiveRecord::Base
audited except: [:globus_uuid, :salesforce_id, :password, :updated, :comments, :experiments, :version, :doi_quota_allowed, :doi_quota_used]

# include helper module for caching infrequently changing resources
include Cacheable
Expand Down Expand Up @@ -56,6 +57,7 @@ class Client < ActiveRecord::Base
has_many :client_prefixes, foreign_key: :datacentre, dependent: :destroy
has_many :prefixes, through: :client_prefixes
has_many :provider_prefixes, through: :client_prefixes
has_many :activities, as: :auditable, dependent: :destroy

before_validation :set_defaults
before_create { self.created = Time.zone.now.utc.iso8601 }
Expand Down
2 changes: 1 addition & 1 deletion app/models/doi.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class Doi < ActiveRecord::Base
# has_many :part_of_events, -> { where target_relation_type_id: "part_of" }, class_name: "Event", primary_key: :doi, foreign_key: :target_doi, dependent: :destroy
# has_many :version_events, -> { where source_relation_type_id: "versions" }, class_name: "Event", primary_key: :doi, foreign_key: :source_doi, dependent: :destroy
# has_many :version_of_events, -> { where target_relation_type_id: "version_of" }, class_name: "Event", primary_key: :doi, foreign_key: :target_doi, dependent: :destroy
has_many :activities, foreign_key: :auditable_id, dependent: :destroy
has_many :activities, as: :auditable, dependent: :destroy
# has_many :source_events, class_name: "Event", primary_key: :doi, foreign_key: :source_doi, dependent: :destroy
# has_many :target_events, class_name: "Event", primary_key: :doi, foreign_key: :target_doi, dependent: :destroy

Expand Down
3 changes: 3 additions & 0 deletions app/models/provider.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
require "countries"

class Provider < ActiveRecord::Base
audited except: [:globus_uuid, :salesforce_id, :password, :updated, :experiments, :comments, :logo, :version, :doi_quota_allowed, :doi_quota_used]

# include helper module for caching infrequently changing resources
include Cacheable

Expand Down Expand Up @@ -72,6 +74,7 @@ class Provider < ActiveRecord::Base
has_many :prefixes, through: :provider_prefixes
has_many :consortium_organizations, class_name: "Provider", primary_key: "symbol", foreign_key: "consortium_id", inverse_of: :consortium
belongs_to :consortium, class_name: "Provider", primary_key: "symbol", foreign_key: "consortium_id", inverse_of: :consortium_organizations, optional: true
has_many :activities, as: :auditable, dependent: :destroy

before_validation :set_region, :set_defaults
before_create { self.created = Time.zone.now.utc.iso8601 }
Expand Down
13 changes: 3 additions & 10 deletions app/serializers/activity_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,16 @@ class ActivitySerializer

attributes "prov:wasGeneratedBy", "prov:generatedAtTime", "prov:wasDerivedFrom", "prov:wasAttributedTo", :action, :version, :changes

belongs_to :doi, record_type: :dois

attribute "prov:wasDerivedFrom" do |object|
url = Rails.env.production? ? "https://doi.org/" : "https://handle.test.datacite.org/"
url + object.uid
object.was_derived_from
end

attribute "prov:wasAttributedTo" do |object|
if object.username.present?
url = Rails.env.production? ? "https://api.datacite.org" : "https://api.test.datacite.org"
object.username.include?(".") ? url + "/clients/" + object.username : url + "/providers/" + object.username
end
object.was_attributed_to
end

attribute "prov:wasGeneratedBy" do |object|
url = Rails.env.production? ? "https://api.datacite.org" : "https://api.test.datacite.org"
"#{url}/activities/#{object.request_uuid}"
object.was_generated_by
end

attribute "prov:generatedAtTime" do |object|
Expand Down
3 changes: 3 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,13 @@
resources :clients, constraints: { id: /.+/ } do
resources :prefixes, constraints: { id: /.+/ }
resources :dois, constraints: { id: /.+/ }
resources :activities
end

resources :repositories, constraints: { id: /.+/ } do
resources :prefixes, constraints: { id: /.+/ }
resources :dois, constraints: { id: /.+/ }
resources :activities
end

resources :client_prefixes, path: "client-prefixes"
Expand Down Expand Up @@ -104,6 +106,7 @@
resources :organizations, constraints: { :id => /.+/ }, shallow: true
resources :dois, constraints: { :id => /.+/ }
resources :prefixes, constraints: { :id => /.+/ }
resources :activities
end
resources :providers, constraints: { :id => /.+/ }
resources :repository_prefixes, path: "repository-prefixes"
Expand Down
36 changes: 20 additions & 16 deletions db/migrate/20190302161113_install_audited.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,23 @@

class InstallAudited < ActiveRecord::Migration[5.2]
def self.up
create_table :audits, force: true do |t|
t.column :auditable_id, :integer
t.column :auditable_type, :string
t.column :associated_id, :integer
t.column :associated_type, :string
t.column :user_id, :integer
t.column :user_type, :string
t.column :username, :string
t.column :action, :string
t.column :audited_changes, :json
t.column :version, :integer, default: 0
t.column :comment, :string
t.column :remote_address, :string
t.column :request_uuid, :string
t.column :created_at, :datetime, limit: 3
safety_assured do
create_table :audits, force: true do |t|
t.column :auditable_id, :integer
t.column :auditable_type, :string
t.column :associated_id, :integer
t.column :associated_type, :string
t.column :user_id, :integer
t.column :user_type, :string
t.column :username, :string
t.column :action, :string
t.column :audited_changes, :json
t.column :version, :integer, default: 0
t.column :comment, :string
t.column :remote_address, :string
t.column :request_uuid, :string
t.column :created_at, :datetime, limit: 3
end
end

add_index :audits, [:auditable_type, :auditable_id, :version], name: "auditable_index"
Expand All @@ -27,6 +29,8 @@ def self.up
end

def self.down
drop_table :audits
safety_assured do
drop_table :audits
end
end
end
Loading

0 comments on commit 4c5f5ed

Please sign in to comment.