DataflowRule.pm 9.04 KB
Newer Older
1
=pod
2 3

=head1 NAME
Jessica Severin's avatar
Jessica Severin committed
4

5
    Bio::EnsEMBL::Hive::DataflowRule
6 7

=head1 DESCRIPTION
Jessica Severin's avatar
Jessica Severin committed
8

9
    A data container object (methods are intelligent getters/setters) that corresponds to a row stored in 'dataflow_rule' table:
10

11
    CREATE TABLE dataflow_rule (
12
        dataflow_rule_id    int(10) unsigned NOT NULL AUTO_INCREMENT,
13 14
        from_analysis_id    int(10) unsigned NOT NULL,
        branch_code         int(10) default 1 NOT NULL,
15
        funnel_dataflow_rule_id  int(10) unsigned default NULL,
16
        to_analysis_url     varchar(255) default '' NOT NULL,
17
        input_id_template   TEXT DEFAULT NULL,
Jessica Severin's avatar
Jessica Severin committed
18

19 20 21 22
        PRIMARY KEY (dataflow_rule_id),
        UNIQUE (from_analysis_id, to_analysis_url)
    );

Leo Gordon's avatar
Leo Gordon committed
23
    A dataflow rule is activated when a Bio::EnsEMBL::Hive::AnalysisJob::dataflow_output_id is called at any moment during a RunnableDB's execution.
24 25 26
    The current RunnableDB's analysis ($from_analysis) and the requested $branch_code (1 by default) define the entry conditions,
    and whatever rules match these conditions will generate new jobs with input_ids specified in the dataflow_output_id() call.
    If input_id_template happens to contain a non-NULL value, it will be used to generate the corresponding intput_id instead.
27

28
    Jessica's remark on the structure of to_analysis_url:
29
        Extended from design of SimpleRule concept to allow the 'to' analysis to be specified with a network savy URL like
30
        mysql://ensadmin:<pass>@ecs2:3361/compara_hive_test/analysis?logic_name='blast_NCBI34'
31

32 33
=head1 LICENSE

34
    Copyright [1999-2015] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute
Matthieu Muffato's avatar
Matthieu Muffato committed
35
    Copyright [2016-2018] EMBL-European Bioinformatics Institute
36 37 38 39 40 41 42 43 44 45

    Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software distributed under the License
    is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and limitations under the License.

46
=head1 CONTACT
Jessica Severin's avatar
Jessica Severin committed
47

48
    Please subscribe to the Hive mailing list:  http://listserver.ebi.ac.uk/mailman/listinfo/ehive-users  to discuss Hive-related questions or to be notified of our updates
49 50 51 52 53 54 55

=cut


package Bio::EnsEMBL::Hive::DataflowRule;

use strict;
56

57 58 59 60
use Bio::EnsEMBL::Utils::Argument ('rearrange');
use Bio::EnsEMBL::Utils::Exception ('throw');

use Bio::EnsEMBL::Hive::Utils ('stringify');
Leo Gordon's avatar
Leo Gordon committed
61
use Bio::EnsEMBL::Hive::DBSQL::AnalysisAdaptor;
62

63 64 65 66
use base (  'Bio::EnsEMBL::Storable',       # inherit dbID(), adaptor() and new() methods
         );


67
=head2 new
68

69
  Usage   : Bio::EnsEMBL::Hive::DataflowRule->new(-from_analysis => $fromAnalysis, -to_analysis => $toAnalysis, -branch_code => $branch_code);
70
  Function: Constructor for DataflowRule object
Jessica Severin's avatar
Jessica Severin committed
71
  Returns : Bio::EnsEMBL::Hive::DataflowRule
72
  Args    : a rearrange-compatible hash
Jessica Severin's avatar
Jessica Severin committed
73
            
74 75 76
=cut

sub new {
77 78
    my $class = shift @_;

79
    my $self = $class->SUPER::new( @_ );    # deal with Storable stuff
80

81 82
    my ($fromAnalysis, $toAnalysis, $from_analysis_id, $branch_code, $funnel_dataflow_rule_id, $to_analysis_url, $input_id_template ) =
    rearrange( [ qw (FROM_ANALYSIS TO_ANALYSIS FROM_ANALYSIS_ID BRANCH_CODE FUNNEL_DATAFLOW_RULE_ID TO_ANALYSIS_URL INPUT_ID_TEMPLATE) ], @_ );
83 84 85 86 87 88

        # from objects:
    $self->from_analysis( $fromAnalysis )           if(defined($fromAnalysis));
    $self->to_analysis( $toAnalysis )               if(defined($toAnalysis));

        # simple scalars:
89 90 91
    $self->from_analysis_id($from_analysis_id)      if(defined($from_analysis_id));
    $self->to_analysis_url($to_analysis_url)        if(defined($to_analysis_url));
    $self->branch_code($branch_code)                if(defined($branch_code));
92
    $self->funnel_dataflow_rule_id($funnel_dataflow_rule_id)  if(defined($funnel_dataflow_rule_id));
93 94 95
    $self->input_id_template($input_id_template)    if(defined($input_id_template));

    return $self;
96 97
}

98

99
=head2 branch_code
Jessica Severin's avatar
Jessica Severin committed
100

101 102
    Function: getter/setter method for the branch_code of the dataflow rule

103
=cut
Jessica Severin's avatar
Jessica Severin committed
104

105
sub branch_code {
106 107
    my $self = shift @_;

108 109 110
    if(@_) {
        my $branch_name_or_code = shift @_;
        $self->{'_branch_code'} = $branch_name_or_code && Bio::EnsEMBL::Hive::DBSQL::DataflowRuleAdaptor::branch_name_2_code( $branch_name_or_code );
111
    }
112
    return $self->{'_branch_code'};
113 114
}

115

116
=head2 funnel_dataflow_rule_id
117

118
    Function: getter/setter method for the funnel_dataflow_rule_id of the dataflow rule
119 120 121

=cut

122
sub funnel_dataflow_rule_id {
123 124 125
    my $self = shift @_;

    if(@_) { # setter mode
126
        $self->{'_funnel_dataflow_rule_id'} = shift @_;
127
    }
128
    return $self->{'_funnel_dataflow_rule_id'};
129 130
}

131

132 133 134 135 136 137 138 139 140
=head2 input_id_template

    Function: getter/setter method for the input_id_template of the dataflow rule

=cut

sub input_id_template {
    my $self = shift @_;

141
    if(@_) {
142 143
        my $input_id_template = shift @_;
        $self->{'_input_id_template'} = (ref($input_id_template) ? stringify($input_id_template) : $input_id_template),
144 145 146
    }
    return $self->{'_input_id_template'};
}
147

148

149
=head2 from_analysis_id
Jessica Severin's avatar
Jessica Severin committed
150

151 152 153 154
  Arg[1]  : (optional) int $dbID
  Usage   : $self->from_analysis_id($dbID);
  Function: Get/set method for the 'from' analysis objects dbID of this rule.
  Returns : integer
Jessica Severin's avatar
Jessica Severin committed
155
  
156
=cut
Jessica Severin's avatar
Jessica Severin committed
157

158 159 160 161 162 163 164 165 166 167 168
sub from_analysis_id {
  my ($self,$analysis_id) = @_;
  if($analysis_id) {
    $self->{'_from_analysis_id'} = $analysis_id;
    $self->{'_from_analysis'} = undef;
  }
  return $self->{'_from_analysis_id'};
}


=head2 to_analysis_url
Jessica Severin's avatar
Jessica Severin committed
169

170 171 172 173
  Arg[1]  : (optional) string $url
  Usage   : $self->to_analysis_url($url);
  Function: Get/set method for the 'to' analysis objects URL for this rule
  Returns : string
Jessica Severin's avatar
Jessica Severin committed
174
  
175
=cut
Jessica Severin's avatar
Jessica Severin committed
176

177 178 179 180 181 182 183 184 185 186 187
sub to_analysis_url {
  my ($self,$url) = @_;
  if($url) {
    $self->{'_to_analysis_url'} = $url;
    $self->{'_to_analysis'} = undef;
  }
  return $self->{'_to_analysis_url'};
}


=head2 from_analysis
Jessica Severin's avatar
Jessica Severin committed
188

189
  Usage   : $self->from_analysis($analysis);
190
  Function: Get/set method for the condition analysis object of this rule.
191 192
  Returns : Bio::EnsEMBL::Hive::Analysis
  Args    : Bio::EnsEMBL::Hive::Analysis
Jessica Severin's avatar
Jessica Severin committed
193
  
194
=cut
Jessica Severin's avatar
Jessica Severin committed
195

196 197 198 199 200
sub from_analysis {
  my ($self,$analysis) = @_;

  # setter mode
  if( defined $analysis ) {
201
    unless ($analysis->isa('Bio::EnsEMBL::Hive::Analysis')) {
202
      throw(
203
        "from_analysis arg must be a [Bio::EnsEMBL::Hive::Analysis]".
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
        "not a [$analysis]");
    }
    $self->{'_from_analysis'} = $analysis;
    $self->{'_from_analysis_id'} = $analysis->dbID;
  }
  
  # lazy load the analysis object if I can
  if(!defined($self->{'_from_analysis'})
     and defined($self->from_analysis_id)
     and defined($self->adaptor))
  {
    $self->{'_from_analysis'} =
      $self->adaptor->db->get_AnalysisAdaptor->fetch_by_dbID($self->from_analysis_id);
  }
  return $self->{'_from_analysis'};
}


=head2 to_analysis
Jessica Severin's avatar
Jessica Severin committed
223

224
  Usage   : $self->to_analysis($analysis);
225
  Function: Get/set method for the goal analysis object of this rule.
226 227
  Returns : Bio::EnsEMBL::Hive::Analysis
  Args    : Bio::EnsEMBL::Hive::Analysis
Jessica Severin's avatar
Jessica Severin committed
228
  
229
=cut
Jessica Severin's avatar
Jessica Severin committed
230

231
sub to_analysis {
232
  my ($self, $analysis_or_nt) = @_;
233

234 235 236
  if( defined $analysis_or_nt ) {
    unless ($analysis_or_nt->can('url')) {
      throw( "to_analysis arg must support 'url' method, '$analysis_or_nt' does not know how to do it");
237
    }
238
    $self->{'_to_analysis'} = $analysis_or_nt;
Jessica Severin's avatar
Jessica Severin committed
239 240 241

    #if the 'from' and 'to' share the same adaptor, then use a simple logic_name
    #for the URL rather than a full network distributed URL
242

Leo Gordon's avatar
Leo Gordon committed
243
    my $ref_rule_adaptor = $self->from_analysis && $self->from_analysis->adaptor;
244

Leo Gordon's avatar
Leo Gordon committed
245
    if($analysis_or_nt->can('logic_name') and $ref_rule_adaptor and ($ref_rule_adaptor == $analysis_or_nt->adaptor)) {
246
      $self->{'_to_analysis_url'} = $analysis_or_nt->logic_name;
247
    } else {
248
      $self->{'_to_analysis_url'} = $analysis_or_nt->url($ref_rule_adaptor->db);
249
    }
250 251 252
  }
  # lazy load the analysis object if I can
  if(!defined($self->{'_to_analysis'}) and defined($self->to_analysis_url)) {
253

Leo Gordon's avatar
Leo Gordon committed
254 255 256 257 258 259
    my $url = $self->to_analysis_url;

    $self->{'_to_analysis'} = $self->adaptor
        ?  $self->adaptor->db->get_AnalysisAdaptor->fetch_by_logic_name_or_url($url)
        :  Bio::EnsEMBL::Hive::DBSQL::AnalysisAdaptor->fetch_by_logic_name_or_url($url)
    or die "Cannot fetch analysis from logic_name or url '$url' for dataflow rule with id='".$self->dbID."'\n";
260

261 262 263 264
  }
  return $self->{'_to_analysis'};
}

265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289

=head2 toString

  Args       : (none)
  Example    : print $df_rule->toString()."\n";
  Description: returns a stringified representation of the rule
  Returntype : string

=cut

sub toString {
    my $self = shift;

    return join('',
            'DataflowRule(dbID=',
            ($self->dbID || '?'),
            ($self->funnel_dataflow_rule_id ? ' --|| '.$self->funnel_dataflow_rule_id : ''),
            '): [#',
            $self->branch_code,
            '] ',
            $self->from_analysis->logic_name,
            ' -> ',
            $self->to_analysis_url,
            ($self->input_id_template ? (' WITH TEMPLATE: '.$self->input_id_template) : ''),
    );
290 291
}

292

293 294
1;