Class: AccessionService::BaseService

Inherits:
Object
  • Object
show all
Includes:
REXML
Defined in:
app/models/accession_service/base_service.rb

Direct Known Subclasses

EGAService, ENAService, NoService, UnsuitableService

Defined Under Namespace

Classes: AccessionedFile

Instance Method Summary collapse

Instance Method Details

#accession_dac_xml(study) ⇒ Object



153
154
155
# File 'app/models/accession_service/base_service.rb', line 153

def accession_dac_xml(study)
  Accessionable::Dac.new(study).xml
end

#accession_policy_xml(study) ⇒ Object



148
149
150
151
# File 'app/models/accession_service/base_service.rb', line 148

def accession_policy_xml(study)
  policy = Accessionable::Policy.new(study)
  policy.xml
end

#accession_sample_xml(sample) ⇒ Object



144
145
146
# File 'app/models/accession_service/base_service.rb', line 144

def accession_sample_xml(sample)
  Accessionable::Sample.new(sample).xml
end

#accession_study_xml(study) ⇒ Object



140
141
142
# File 'app/models/accession_service/base_service.rb', line 140

def accession_study_xml(study)
  Accessionable::Study.new(study).xml
end

#dac_visibility(_study) ⇒ Object



169
170
171
# File 'app/models/accession_service/base_service.rb', line 169

def dac_visibility(_study)
  AccessionService::PROTECT
end

#policy_visibility(_study) ⇒ Object



165
166
167
# File 'app/models/accession_service/base_service.rb', line 165

def policy_visibility(_study)
  AccessionService::PROTECT
end

#private?Boolean

Returns:

  • (Boolean)


173
174
175
# File 'app/models/accession_service/base_service.rb', line 173

def private?
  false
end

#providerObject



9
10
# File 'app/models/accession_service/base_service.rb', line 9

def provider
end

#sample_visibility(_sample) ⇒ Object



157
158
159
# File 'app/models/accession_service/base_service.rb', line 157

def sample_visibility(_sample)
  AccessionService::PROTECT
end

#study_visibility(_study) ⇒ Object



161
162
163
# File 'app/models/accession_service/base_service.rb', line 161

def study_visibility(_study)
  AccessionService::PROTECT
end

#submit(user, *accessionables) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'app/models/accession_service/base_service.rb', line 32

def submit(user, *accessionables)
  ActiveRecord::Base.transaction do
    submission = Accessionable::Submission.new(self, user, *accessionables)

    errors = submission.all_accessionables.map(&:errors).flatten

    raise AccessionService::AccessionServiceError, errors.join("\n") unless errors.empty?

    files = [] # maybe not necessary, but just to be sure that the tempfile still exists when they are sent
    begin
      xml_result =
        post_files(
          submission.all_accessionables.map do |acc|
            file = Tempfile.open("#{acc.schema_type}_file")
            files << file
            file.puts(acc.xml)
            file.open # reopen for read

            Rails.logger.debug { file.each_line.to_a.join("\n") }

            { name: acc.schema_type.upcase, local_name: file.path, remote_name: acc.file_name }
          end
        )
      Rails.logger.debug { xml_result }
      if xml_result.match?(/(Server error|Auth required|Login failed)/)
        raise AccessionService::AccessionServiceError,
              "EBI Server Error. Could not get accession number: #{xml_result}"
      end

      xmldoc = Document.new(xml_result)
      success = xmldoc.root.attributes['success']
      accession_numbers = []

      # for some reasons, ebi doesn't give us back a accession number for the submission if it's a MODIFY action
      # therefore, we should be ready to get one or not
      number_generated = true
      case success
      when 'true'
        # extract and update accession numbers
        accession_number =
          submission.all_accessionables.each do |acc|
            accession_number = acc.extract_accession_number(xmldoc)
            if accession_number
              acc.update_accession_number!(user, accession_number)
              accession_numbers << accession_number
            else
              # error only, if one of the expected accessionable didn't get a AN
              # We don't care about the submission
              number_generated = false if accessionables.include?(acc)
            end
            ae_an = acc.extract_array_express_accession_number(xmldoc)
            acc.update_array_express_accession_number!(ae_an) if ae_an
          end

        raise AccessionService::NumberNotGenerated, 'Service gave no numbers back' unless number_generated
      when 'false'
        errors = xmldoc.root.elements.to_a('//ERROR').map(&:text)
        current_error = errors.first
        message = "Current error is: '#{current_error}'"
        more_messages = "There are #{errors.length - 1} more errors." if errors.many?
        raise AccessionService::AccessionServiceError,
              ['Could not get accession number. Error in submitted data:', $!.to_s, message,
               more_messages].compact.join(' ')
      else
        raise AccessionService::AccessionServiceError,
              "Could not get accession number. Error in submitted data: #{$!}"
      end
    ensure
      files.each(&:close) # not really necessary but recommended
    end
  end

  accessionables.map(&:accession_number)
end

#submit_dac_for_user(_study, _user) ⇒ Object



136
137
138
# File 'app/models/accession_service/base_service.rb', line 136

def submit_dac_for_user(_study, _user)
  raise AccessionService::NumberNotRequired, 'No need to'
end

#submit_sample_for_user(sample, user) ⇒ Object



107
108
109
110
111
112
# File 'app/models/accession_service/base_service.rb', line 107

def submit_sample_for_user(sample, user)
  # TODO: commented out line as not used without error handling
  # ebi_accession_number = sample.sample_metadata.sample_ebi_accession_number

  submit(user, Accessionable::Sample.new(sample))
end

#submit_study_for_user(study, user) ⇒ Object



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'app/models/accession_service/base_service.rb', line 114

def submit_study_for_user(study, user)
  unless study.accession_required?
    raise AccessionService::NumberNotRequired,
          'An accession number is not required for this study'
  end

  # Flag set in the deployment project to allow per-environment enabling of accessioning
  unless configatron.accession_samples
    raise AccessionService::AccessioningDisabledError, 'Accessioning is not enabled in this environment.'
  end

  # TODO: check error
  # raise AccessionServiceError, "Cannot generate accession number: #{ sampledata[:error] }" if sampledata[:error]

  # TODO: commented as not used without error handling
  # ebi_accession_number = study.study_metadata.study_ebi_accession_number

  # raise NumberNotGenerated, 'No need to' if not ebi_accession_number.blank? and not /ER/.match(ebi_accession_number)

  submit(user, Accessionable::Study.new(study))
end