Subversion Repositories Web Services

Rev

Rev 118292 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
82190 hhl 1
<?php
2
/**
3
 *
4
 * This file is part of Open Library System.
5
 * Copyright © 2013, Dansk Bibliotekscenter a/s,
6
 * Tempovej 7-11, DK-2750 Ballerup, Denmark. CVR: 15149043
7
 *
8
 * Open Library System is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * Open Library System is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU Affero General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Affero General Public License
19
 * along with Open Library System.  If not, see <http://www.gnu.org/licenses/>.
118292 fvs 20
 */
82190 hhl 21
 
22
 
23
require_once 'OLS_class_lib/memcache_class.php';
24
 
25
/**
26
 * \brief Class for formatting records from fedora object repository
27
 *   records are split according to record_blocking and send to one or more formating servers
28
 *
29
 * Usage: \n
118292 fvs 30
 *    $formater = new formatRecords($config_array, $namespace, $objconverter, $xmlconverter [, $timer]);
31
 * $formatted_records = $formater->format($records, $param);
82190 hhl 32
 *
33
 * Example:
34
 *   $formatRecords = new formatRecords($this->config->get_section('setup'), $this->xmlns['of'], $this->objconvert, $this->xmlconvert, $this->watch);
35
 *   $formatted = $formatRecords->format($form_req, $param);
36
 *
37
 * @author Finn Stausgaard - DBC
38
 */
39
class FormatRecords {
40
  protected $cache;                     ///< for caching formatted records
41
  protected $curl;                      ///< the curl connection
42
  protected $namespace;                 ///< the namespace for openformat
43
  protected $objconvert;                ///< OLS object to xml convert
44
  protected $xmlconvert;                ///< xml to OLS object convert
45
  protected $watch;                     ///< timer object
46
  protected $record_blocking = 1;       ///< block factor: number of records in each request to js_server
47
  protected $js_server_url = array();   ///< if more than one, the formatting requests will be split amongst them
48
  protected $rec_status = array();      ///< curl_status for each record formattet
49
  protected $timeout = 5;               ///< -
50
 
51
  /** \brief
118292 fvs 52
   * @param $setup object
53
   * @param $namespace string
54
   * @param $objconvert class
55
   * @param $xmlconvert class
56
   * @param $watch class optional
57
   */
82190 hhl 58
  public function __construct($setup, $namespace, &$objconvert, &$xmlconvert, &$watch = NULL) {
59
    $this->curl = new curl();
60
    foreach ($setup['js_server'] as $url) {
61
      $this->js_server_url[] = $url;
62
    }
118292 fvs 63
    if (!($this->timeout = (integer)$setup['curl_timeout'])) {
82190 hhl 64
      $this->timeout = 5;
65
    }
118292 fvs 66
    // Since the api for record_blocking is not defined, it will be set to 1
67
    //  if (!($this->record_blocking = (integer) $setup['record_blocking'])) {
68
    $this->record_blocking = 1;
69
    //  }
82190 hhl 70
    $this->cache = new cache($setup['cache_host'], $setup['cache_port'], $setup['cache_expire']);
71
 
72
    $this->curl = new curl();
73
    $this->namespace = $namespace;
74
    $this->objconvert = $objconvert;
75
    $this->xmlconvert = $xmlconvert;
76
    $this->watch = $watch;
77
  }
78
 
79
  /** \brief
118292 fvs 80
   * @param $records array Records to format
81
   * @param $param object User given parameters
82
   * @return array - of formatted records
83
   */
82190 hhl 84
  public function format($records, $param) {
85
    static $dom;
86
    if (empty($dom)) {
87
      $dom = new DomDocument();
88
      $dom->preserveWhiteSpace = false;
89
    }
90
    $output_format = $param->outputFormat->_value;
100084 fvs 91
    $form_req = new stdClass();
92
    $form_req->formatSingleManifestationRequest = new stdClass();
93
    $form_req->formatSingleManifestationRequest->_value = new stdClass();
82190 hhl 94
    $form_req->formatSingleManifestationRequest->_value->agency = $param->agency;
95
    $form_req->formatSingleManifestationRequest->_value->holdBackEndDate = $param->holdBackEndDate;
96
    $form_req->formatSingleManifestationRequest->_value->language = $param->language;
97
    $form_req->formatSingleManifestationRequest->_value->outputFormat = $param->outputFormat;
98
    $form_req->formatSingleManifestationRequest->_value->trackingId = $param->trackingId;
99
    $ret = array();
100
    $ret_index = array();  // to make future caching easier
101
    $curls = 0;
102
    $tot_curls = 0;
103
    $next_js_server = rand(0, count($this->js_server_url) - 1);
104
    for ($no = 0; $no < count($records); $no = $no + $this->record_blocking) {
105
      $cache_key[$curls] = self::make_cache_key($records[$no]->_value->collection->_value->object, $param);
106
      if ($ret[$no] = $this->cache->get($cache_key[$curls])) {
120114 fvs 107
        self::local_verbose(DEBUG, 'format cache hit ' . $cache_key[$curls]);
82190 hhl 108
        continue;
109
      }
120114 fvs 110
      self::local_verbose(DEBUG, 'no format cache hit');
82190 hhl 111
      $ret_index[$curls] = $no;
112
      $form_req->formatSingleManifestationRequest->_value->originalData = &$records[$tot_curls];
113
      $this->curl->set_option(CURLOPT_TIMEOUT, $this->timeout, $curls);
114
      $this->curl->set_option(CURLOPT_HTTPHEADER, array('Content-Type: text/xml; charset=UTF-8'), $curls);
115
      $this->curl->set_url($this->js_server_url[$next_js_server], $curls);
116
      $rec = $this->objconvert->obj2xmlNs($form_req);
117
      $this->curl->set_post_xml($rec, $curls);
118
      $curls++;
119
      $tot_curls++;
120
      if ($curls == count($this->js_server_url) || $tot_curls == count($records)) {
121
        if (is_object($this->watch)) {
122
          $this->watch->start('js_server');
123
        }
124
        $js_result = $this->curl->get();
125
        $curl_status = $this->curl->get_status();
126
        if (is_object($this->watch)) {
127
          $this->watch->stop('js_server');
128
        }
129
        if ($curl_status['url']) $curl_status = array($curl_status);
130
        if (!is_array($js_result)) $js_result = array($js_result);
131
        for ($i = 0; $i < $curls; $i++) {
132
          $this->rec_status[] = $curl_status[$i];
133
          if ($curl_status[$i]['http_code'] == 200) {
134
            if (@ $dom->loadXML($js_result[$i])) {
135
              $js_obj = $this->xmlconvert->xml2obj($dom);
136
            }
137
            else {
138
              $error = 'Error formatting record - no valid response';
139
            }
140
          }
141
          else {
120114 fvs 142
            self::local_verbose(ERROR, 'http code: ' . $curl_status[$i]['http_code'] .
118292 fvs 143
                              ' error: "' . $curl_status[$i]['error'] .
144
                              '" for: ' . $curl_status[$i]['url'] .
145
                              ' TId: ' . $param->trackingId->_value);
82190 hhl 146
            $error = 'HTTP error ' . $curl_status[$i]['http_code'] . ' . formatting record';
147
          }
148
          if ($error) {
100086 fvs 149
            $js_obj = new stdClass();
150
            $js_obj->{$output_format} = new stdClass();
151
            $js_obj->{$output_format}->_value = new stdClass();
152
            $js_obj->{$output_format}->_value->error = new stdClass();
82190 hhl 153
            $js_obj->{$output_format}->_namespace = $this->namespace;
154
            $js_obj->{$output_format}->_value->error->_value = $error;
155
            $js_obj->{$output_format}->_value->error->_namespace = $this->namespace;
156
            unset($error);
157
          }
158
          $this->cache->set($cache_key[$i], $js_obj);
159
          $ret[$ret_index[$i]] = $js_obj;
160
        }
161
        $curls = 0;
162
      }
163
      $next_js_server = ++$next_js_server % count($this->js_server_url);
164
    }
165
    return $ret;
166
  }
167
 
168
  /** \brief setters
118292 fvs 169
   * @param $count integer
170
   */
82190 hhl 171
  public function set_record_blocking($count) {
118292 fvs 172
    $this->record_blocking = (integer)$count;
82190 hhl 173
  }
174
 
175
  /** \brief setters
118292 fvs 176
   * @param $seconds integer
177
   */
82190 hhl 178
  public function set_timeout($seconds) {
118292 fvs 179
    $this->timeout = (integer)$seconds;
82190 hhl 180
  }
181
 
182
  /** \brief getters
118292 fvs 183
   * @return array of status
184
   *
185
   */
82190 hhl 186
  public function get_status() {
187
    return $this->rec_status;
188
  }
189
 
190
  /** \brief generate hash key from the record and the user params
118292 fvs 191
   * @param $record object the records to format
192
   * @param $param object the usergiven parameters
193
   * @return string cache key for the object
194
   */
82190 hhl 195
  private function make_cache_key(&$record, &$param) {
196
    if (is_array($record)) {
197
      foreach ($record as &$man) {
198
        $key .= $man->_value->identifier->_value . '_';
199
      }
200
    }
201
    else {
202
      $key = $record->_value->identifier->_value . '_';
203
    }
118292 fvs 204
    return 'OF_' . md5($key .
205
                       $param->agency->_value . '_' .
206
                       $param->holdBackEndDate->_value . '_' .
207
                       $param->language->_value . '_' .
208
                       $param->outputFormat->_value);
82190 hhl 209
  }
210
 
120114 fvs 211
  /** \brief -
212
   * @param string $level
213
   * @param string $msg
214
   */
215
  private function local_verbose($level, $msg) {
216
    if (method_exists('VerboseJson', 'log')) {
217
      VerboseJson::log($level, $msg);
218
    }
219
    elseif (method_exists('verbose', 'log')) {
220
      verbose::log($level, $msg);
221
    }
222
  }
82190 hhl 223
}