GOCDB/PI/Technical Documentation/client php

From EGIWiki
Jump to: navigation, search
Main EGI.eu operations services Support Documentation Tools Activities Performance Technology Catch-all Services Resource Allocation Security


GOC DB menu: Home Documentation Index


Provided by Guillaume Cessieux, CC-IN2P3. The following example shows a simple PHP class with methods used to retrieve and parse XML data from GOCDB-PI using PHP curl and simplexml


<?php

$gocdb = new GocDB(4); # Can be instanciated with GocDB(3) for GOCDB3

# ----------------------------

# Sample Calls

# Return time in ms of a simple query or false if failure
var_dump($gocdb->test());

#var_dump($gocdb->base_query('https://next.gocdb.eu/gocdbpi/public/?method=get_service_endpoint&sitename=IN2P3-CC'));

#var_dump($gocdb->base_query('https://next.gocdb.eu/gocdbpi/public/?method=get_service_endpoint&sitename=GRIDOPS-GOCDB'));

# ?method=get_site_list&sitename=RAL-LCG2
#var_dump($gocdb->query('get_site_list', array('sitename' => 'RAL-LCG2')));

# Wrong method called
#var_dump($gocdb->query('get_site_contactsOUUUPS', array('country' => 'Poland')));

# ?method=get_service_types
#var_dump($gocdb->query('get_service_types'));

# ?method=get_site_contacts&country=Poland
#var_dump($gocdb->query('get_site_contacts', array('country' => 'Poland'), 'private'));

# Private method now supported - Only add 'private' parameter

# ?method=get_site&sitename=RAL-LCG2
#var_dump($gocdb->query('get_site', array('sitename' => 'RAL-LCG2'), 'private'));

# ?method=get_site&roc=GermanySwitzerland
#var_dump($gocdb->query('get_site', array('roc' => 'GermanySwitzerland'), 'private'));

# https://goc.gridops.org/gocdbpi/private/?method=get_site_contacts&sitename=RAL-LCG2
# var_dump($gocdb->query('get_site_contacts', array('sitename' => 'RAL-LCG2'), 'private'));

#?method=get_user&dn=/C=ZZ/O=certif/OU=users/OU=roc.com/CN=Foo Bar
# return false as no result
#var_dump($gocdb->query('get_user', array('dn' => '/C=ZZ/O=certif/OU=users/OU=roc.com/CN=Foo Bar'), 'private'));

# In development

# supported in the future?
#var_dump($gocdb->query('get_site_list', array(array('sitename' => 'RAL-LCG2'), array('sitename' => 'CCIN2P3'))));

# If memory exausted of these method just increase php memory size (16MB seems fine) or reduce the scope of the query
#var_dump($gocdb->query('get_downtime'));

# This one always works fine
#var_dump($gocdb->query('get_downtime', array('startdate' => '2009-02-01')));

# ----------------------------


if (isset($argv[1]) && $argv[1] == 'test')
{ # Enable an easy testing call - return 1 if gocdb not reached/working
  exit ($gocdb->test() ? 0 : 1);
}

Class GocDB
{
  public $base_url = null;
  public static $version = "ENOC GOCDB API interface v0.4";

  function __construct($gocdb_version = 4)  # default is GOCDB4
    {
      static $url_gocdb_4 = 'https://next.gocdb.eu/gocdbpi/';
      static $url_gocdb_3 = 'https://goc.gridops.org/gocdbpi/';

      $vname = "url_gocdb_" . $gocdb_version;
      if (isset($$vname))
    $this->base_url = $$vname;
      else
    {
      echo __FILE__ . '('. __LINE__ . '): ' . "Error unrecognised version of GOCDB, defaulting to v4\n";
      $this->base_url = $url_gocdb_4;
    }
      $this->debug("GOCDB instance created with base url " . $this->base_url . "\n");
    }


  # return XML if ok, NULL if error, false if empty result.
  function query($method, $parameters = null, $kind = 'public')
    {
      $this->debug("URL fetched: ". $this->url_query_builder($method, $parameters, $kind));
      $result = $this->base_query($this->url_query_builder($method, $parameters, $kind));
      return ($this->is_error($result) ? null : $result);
    }

  function url_query_builder($method, $parameters = null, $kind = 'public')
    {
      assert($kind == 'public' || $kind == 'private');
      $url = $this->base_url . $kind . "/?method=$method";
      if ($parameters && isset($parameters[0]))
    foreach ($parameters as $param)
      foreach ($param as $key => $value)
        $url .= "&$key=" . urlencode($value);
      else if ($parameters)
    foreach ($parameters as $key => $value)
      $url .= "&$key=" . urlencode($value);
      return $url;
    }

  function test()
    { # return false if failled, time in ms if succeed
      $s = microtime (true);
    $xml = $this->query('get_site_list', array('sitename' => 'IN2P3-CC'));
    if (!$xml || !isset($xml->SITE['ID']) || $xml->SITE['ID'] != '28')
      return false;
    return round((microtime(true) - $s) * 1000);
    }

  function is_error($result)
    {
      if (isset($result->error_message))
    {
      echo __FILE__ . '('. __LINE__ . '): ' . "Error found in result: ". $result->error_message . "\n";
      return true;
    }
      return false;

    }

  function do_request($url)
    {
      if (!$data = $this->get_https($url))
    {
      echo __FILE__ . '('. __LINE__ . '): ' . "Unable to read data in url '$url'\n";
      var_dump($data);
      return null;
    }
      return $data;
    }

  function load_data($data)
    {
# empty result seem not considered by valid xml by simplexml_load_string - with utf-8 BOM
      if ($data == "<?xml version=\"1.0\"?>\n<ROOT/>\n" || $data == "\xEF\xBB\xBF<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<results/>\n")
    return false;

      if (!$xml = @simplexml_load_string($data))
    {
      var_dump($xml);
      echo __FILE__ . '('. __LINE__ . '): ' . "Invalid xml data gathered\n";
      return null;
    }
      return $xml;
    }

  function base_query($url)
    {
      if($res = $this->do_request($url))
    return $this->load_data($res);
      return null;
    }


  private function debug($str)
    {
#      echo __FILE__ . '('. __LINE__ . '): ' . "$str\n";
    }

  private function get_https($url)
    {
      $handle = curl_init();

      $curloptions = array (
      CURLOPT_RETURNTRANSFER => false,
      CURLOPT_HEADER         => false,
      CURLOPT_FOLLOWLOCATION => true,
      CURLOPT_MAXREDIRS      => 1,
      CURLOPT_SSL_VERIFYHOST => '1',
      CURLOPT_SSL_VERIFYPEER => '1',
      CURLOPT_USERAGENT      => GocDB::$version,
      CURLOPT_VERBOSE        => false,
      CURLOPT_URL            => $url,
      CURLOPT_RETURNTRANSFER => '1',
      CURLOPT_CAPATH => '/etc/grid-security/certificates/',
      # cat crt.key crt.pem > crt.both to have curl accepting it !
      CURLOPT_SSLCERT => '/etc/httpd/conf/certif-grid-server/ccenoc.in2p3.fr.both',
      CURLOPT_SSLCERTTYPE => 'PEM',
    );


      if (str_replace('.', '', phpversion()) < 513)
    {
      foreach ($curloptions as $optname => $value)
        curl_setopt($handle, $optname, $value);
    }
      else # php > 1.5.3 nice feature provided
            curl_setopt_array($handle, $curloptions);

      $return = curl_exec($handle);
      if (curl_errno($handle)) {
    echo __FILE__ . '('. __LINE__ . '): ' . 'Error: ' . curl_error($handle);
      }
      curl_close($handle);

    if ($return == false)
      print_r(curl_getinfo($handle));
    return $return;
  }
}

?>