API - PID generation

Every identifier consists of two parts: its prefix and a unique local name under the prefix known as its suffix

< PREFIX > / < SUFFIX > (e.g. 11239/123456745).

Any suffix - local name must be unique under its local namespace. The uniqueness of a prefix and a local name under that prefix ensures that any identifier is globally unique within the context of the System.

Depending on the service there are two ways to generate the SUFFIX a) automatic and b) manual

Automatic generation of SUFFIX

The API supports the automatic generation of a local name - suffix by using a generator via a POST Request. This generator uses UUIDs to guarantee the uniqueness of created handles. The syntax follows the following pattern

SUFFIX = prefix - UUID - suffix

where

Example

In this example we are going to use the automatic creation of PID. The automatic generation of PID is executed using a POST HTTP Request.

The request in curl


curl -v -u "YOURUSERNAME:YOURPASSWORD" -H "Accept:application/json" -H "Content-Type:application/json" -X POST --data '[{"type":"URL","parsed_data":"http://www.grnet.gr/"}]' https://epic.grnet.gr/api/v2/handles/11239/\?prefix=GRNET\&suffix=TEST

The request in python. The main difference is that you have to do a POST request.

import urllib2
import uuid
import json

PIDSERVICE_URL="THE_SERVICE_URL_WITH_PREFIX"
PIDSERVICE_USER="YOURUSERNAME"
PIDSERVICE_PASSWD="YOURPASSWORD"
SUFFIX ="?prefix=GRNET&suffix=test"
URL_TO_OPEN=PIDSERVICE_URL+SUFFIX
DATAURL=''

# create a password manager
password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()

# Add the username and password.
password_mgr.add_password(None, PIDSERVICE_URL, PIDSERVICE_USER, PIDSERVICE_PASSWD)

handler = urllib2.HTTPBasicAuthHandler(password_mgr)

# create "opener" (OpenerDirector instance)
opener = urllib2.build_opener(handler)

# use the opener to fetch a URL
opener.open(PIDSERVICE_URL)

# Install the opener.
# Now all calls to urllib2.urlopen use the created opener.
urllib2.install_opener(opener)

#create the json data
JSONDATA = [{'type':'URL','parsed_data':'http://www.grnet.gr'}]
JSONDATATOSEND = json.dumps(JSONDATA);

REQUESTDATA = urllib2.Request(URL_TO_OPEN, data=JSONDATATOSEND)

#create the headers
REQUESTDATA.add_header('Content-Type','application/json')
REQUESTDATA.add_header('Content-Length',len(JSONDATATOSEND))

# creates the POST method
REQUESTDATA.get_method = lambda: 'POST'

try:
    DATAURL = urllib2.urlopen(REQUESTDATA)
    
except urllib2.URLError, e:
    print e
    if e.code == 404:
        print "404-Not found"
    if e.code == 401:
        print "401-Authentication failed"    
        #get http code of the request

if DATAURL:
    # Getting the code
    print "This gets the code: ", DATAURL.code

The request in php

$PIDSERVICE_URL="THE_SERVICE_URL_WITH_PREFIX";
$PIDSERVICE_USER="YOURUSERNAME";
$PIDSERVICE_PASSWD="YOURPASSWORD";
$UUID = "?prefix=GRNET&suffix=TEST";
$URL_TO_OPEN = $PIDSERVICE_URL.$UUID;
$data = array(array('type' => 'URL','parsed_data'=>'http://www.grnet.gr/'));
$update_json=json_encode($data);

// Get cURL resource
$ch = curl_init();

//Set the headers to complete the request
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json','Content-Length: ' . strlen($update_json)));

//set the POST Action
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");

//SET the postfield data
curl_setopt($ch, CURLOPT_POSTFIELDS,$update_json);

// Should cURL return or print out the data? (true = return, false = print)
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

//Set the url with the new name of the PID 
curl_setopt($ch, CURLOPT_URL, $URL_TO_OPEN);

// Set the authentication options
curl_setopt($ch, CURLOPT_USERPWD, $PIDSERVICE_USER.":".$PIDSERVICE_PASSWD);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);

$output = curl_exec($ch);
$info = curl_getinfo($ch);

// Download the given URL, and return output 

if( $info['http_code']==200) echo "HANDLE EXISTS";
if( $info['http_code']==201) echo "PID CREATED";
if( $info['http_code']==204) echo "PID UPDATED";
if( $info['http_code']==404) echo "HANDLE DOESNT EXIST";

curl_close($ch);

The request in perl

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;
use Getopt::Long;
use Switch 'Perl5', 'Perl6';
use JSON;
use WWW::Curl::Easy;

my $fullargv0 = $0;
my ($argv0) = $fullargv0 =~ /([^\/\\]+)$/;

my %settings = (
'debug' => 'False',
'handle' => {
	'action' =>'put',
	'credentials' 	=>	{
		'username'	=> 'empty',
		'password'	=> 'empty',
		'baseuri'	=> 'empty',
	},
	'data'	=>{
		'get'	=> '',
		'putpost'=> '',
	},
	'format' => 'none',
	'headerextra'	=> '',
	'type' => 'none',
	'url'=>	{
		'pid'=> 'prefix=GRNET&suffix=TEST',
	},
},
);

# Main subroutine
sub main {

	#Get the subroutine arguments
	my $settings_ref = shift;

	# Get the script arguments
	(my $returncode) = get_arguments($settings_ref);

	if( $returncode == 0 ) 
	 performPost($settings_ref);

	return($returncode);
}
 
# Subroutine to perform a POST action
sub performPost {

	# Get the subroutine arguments
	my $settings_ref = shift;

	#construct url and headers
	my $url="$settings_ref->{handle}->{credentials}->{baseuri}$settings_ref->{handle}->{url}->{pid}";
	printf("The constructed url is        : %s\n",$url) if $settings_ref->{debug} =~ /True/ ;
	my @httpHeaders = ( 'Content-Type: application/json' );

	#construct data
	my $data=$settings_ref->{handle}->{data}->{putpost};
	printf("The data is                   : %s\n",$data) if $settings_ref->{debug} =~ /True/ ;

	# perform action
	(my $returncode, my $response_code, my $response_content_type, my $response_url ) = httpPost($settings_ref, $url, \@httpHeaders, $data );

	# Looking at the results of the curl request
	if ($returncode == 0) {
		print('Transfer went ok\n') if $settings_ref->{debug} =~ /True/ ;

		# judge result and next action based on $response_code
		if ($response_code >= 200 && $response_code < 300 ) {
			print('The request went ok\n') if $settings_ref->{debug} =~ /True/ ;
			print("$response_url\n");
		} else {
			print('The request went NOT ok\n') if $settings_ref->{debug} =~ /True/ ;
			print("$response_code\n");
		} 

	} else {
		print('An error happened\n');
	}
}

# reader helper calback function
sub read_callback {
	my ($maxlength,$pointer)=@_;
	# printf("The MAXLENGTH is     : \n", $maxlength);
	# printf("The POINTER is       : \n", $$pointer) ;
	my $data = $$pointer;
	$$pointer = "";
	return $data;
}

# Subroutine to post data via a http POST
sub httpPost {

	# Get the subroutine arguments
	my $settings_ref = shift;
	my $url = shift;
	my $httpHeaders_ref = shift;
	my $data = shift;

	print('Entering httpPost             :\n')         if $settings_ref->{debug} =~ /True/;

	# local varables
	my $body = "";
	my $header = "";
	my $response_body;
	my $response_code;
	my $response_content_type;
	my $response_url = "";

	my $curl = WWW::Curl::Easy->new;

	# set options for the curl http request
	$curl->setopt(CURLOPT_HEADER, 1);
	$curl->setopt(CURLOPT_HTTPHEADER, $httpHeaders_ref );
	$curl->setopt(CURLOPT_POST, 1);
	$curl->setopt(CURLOPT_POSTFIELDS, $data);
	$curl->setopt(CURLOPT_POSTFIELDSIZE, length($data)) ;
	$curl->setopt(CURLOPT_URL, $url);
	$curl->setopt(CURLOPT_USERNAME, $settings_ref->{handle}->{credentials}->{username});
	$curl->setopt(CURLOPT_PASSWORD, $settings_ref->{handle}->{credentials}->{password});

	#debugging
	#$curl->setopt (CURLOPT_VERBOSE, 1);

	# A filehandle, reference to a scalar or reference to a typeglob can be used here.
	open my $fh, '>:encoding(UTF-8)', \$response_body or die "$!";
	$curl->setopt(CURLOPT_WRITEDATA, $fh);

	# Do the actual curl http request
	my $returncode = $curl->perform;

	# close file handle
	close($fh);

	# Looking at the results of the curl request
	if ($returncode == 0) {
		print('Transfer went ok\n') if $settings_ref->{debug} =~ /True/ ;
		$response_code         = $curl->getinfo(CURLINFO_HTTP_CODE);
		$response_content_type = $curl->getinfo(CURLINFO_CONTENT_TYPE);
		print("Received response code        : $response_code\n")         if $settings_ref->{debug} =~ /True/;
		print("Received response content type: $response_content_type\n") if $settings_ref->{debug} =~ /True/;

		# judge result and next action based on $response_code
		if ($response_code >= 200 && $response_code < 300 ) {
			print('The request went ok\n') if $settings_ref->{debug} =~ /True/ ;
			print("$response_body\n") if $settings_ref->{debug} =~ /True/;
			open my $fh, '<:encoding(UTF-8)', \$response_body or die "$!";
			while (my $row = <$fh>) {
				chomp $row;
				print "row: $row\n" if $settings_ref->{debug} =~ /True/;
				if ( $row =~ /^Location/ ) {
					$response_url = $row;
					$response_url =~ s/^Location: // ;
					print("Received response url         : $response_url\n") if $settings_ref->{debug} =~ /True/;
					last;
				}
			}

		} else {
			print('The request went NOT ok\n') if $settings_ref->{debug} =~ /True/ ;
			print("$response_code\n") if $settings_ref->{debug} =~ /True/;
		} 

	} else {
		# Error code, type of error, error message
		print("An error happened: $returncode ".$curl->strerror($returncode)." ".$curl->errbuf."\n");
	}

	# Return the results
	return($returncode, $response_code, $response_content_type, $response_url );
}

# Subroutine to get and check all script arguments
sub get_arguments {

	# Get the subroutine arguments
	my $settings_ref = shift;

	# Define local variables
	my %arguments;
	my $username;
	my $password;
	my $baseUri;
	my $pidUrl;
	my $credentials;
	my $handleData;
	my $type;
	my $header;
	my $returncode=0;
	my $message;
	my @sources;

	GetOptions( 'h|help'    => \$arguments{help},
		'user=s'		=> \$username,
		'passwd=s'		=> \$password,
		'base=s'		=> \$baseUri,
		'pid=s'			=> \$pidUrl,
		'cred=s'		=> \$credentials,
		'data=s'		=> \$handleData,
		'type=s'		=> \$type,
		'header=s'		=> \$header,
		'get'			=> \$arguments{get},
		'put'			=> \$arguments{put},
		'delete'		=> \$arguments{delete},
		'post'			=> \$arguments{post},
		'pretty'		=> \$arguments{pretty},
		'd|debug'		=> \$arguments{debug},
	);

	# Check the help flag
	if( $arguments{help} ) {

		# Set the returncode
		$returncode=255;

		$message = print_help();
	}
	
	# Check the debug flag
	if( $arguments{debug} ) {

		$settings_ref->{debug} = 'True';
		printf('debug is                      : on\n') if $settings_ref->{debug} =~ /True/ ;

	}

	# Check the pretty flag
	if( $arguments{pretty} ) {

		$settings_ref->{handle}->{format} = 'pretty';
		printf('pretty format printing is     : on\n') if $settings_ref->{debug} =~ /True/ ;

	}

	# Check the action flag's (get,put,delete,post,search,nagios)
	if( $arguments{get} ) {

		$settings_ref->{handle}->{action} = 'get';
		printf("The action is                 : %s\n", $settings_ref->{handle}->{action}) if $settings_ref->{debug} =~ /True/ ;

	} elsif ( $arguments{put} ) {

		$settings_ref->{handle}->{action} = 'put';
		printf("The action is                 : %s\n", $settings_ref->{handle}->{action}) if $settings_ref->{debug} =~ /True/ ;

	} elsif ( $arguments{delete} ) {

		$settings_ref->{handle}->{action} = 'delete';
		printf("The action is                 : %s\n", $settings_ref->{handle}->{action}) if $settings_ref->{debug} =~ /True/ ;

	} elsif ( $arguments{post} ) {

		$settings_ref->{handle}->{action} = 'post';
		printf("The action is                 : %s\n", $settings_ref->{handle}->{action}) if $settings_ref->{debug} =~ /True/ ;

	}

	# check the username
	if( $username ) {

		$settings_ref->{handle}->{credentials}->{username} = $username;
		printf("The username is               : %s\n",$settings_ref->{handle}->{credentials}->{username}) if $settings_ref->{debug} =~ /True/ ;

	}

	# check the password
	if( $password ) {

		$settings_ref->{handle}->{credentials}->{password} = $password;
		printf("The password is               : %s\n",$settings_ref->{handle}->{credentials}->{password}) if $settings_ref->{debug} =~ /True/ ;

	}

	# check the base uri
	if( $baseUri ) {

		$settings_ref->{handle}->{credentials}->{baseuri} = $baseUri;
		printf("The base uri is               : %s\n",$settings_ref->{handle}->{credentials}->{baseuri}) if $settings_ref->{debug} =~ /True/ ;

	}

	# check the pid url
	if( $pidUrl ) {

		$settings_ref->{handle}->{url}->{pid} = $pidUrl;
		printf("The pid is                    : %s\n",$settings_ref->{handle}->{url}->{pid}) if $settings_ref->{debug} =~ /True/ ;
	
	}

	# check the handle data
	if( $handleData ) {

		$settings_ref->{handle}->{data}->{putpost} = $handleData;
		printf("The data is                   : %s\n",$settings_ref->{handle}->{data}->{putpost}) if $settings_ref->{debug} =~ /True/ ;
	
	}

	# check the type data
	if( $type ) {

		$settings_ref->{handle}->{type} = $type;
		printf("The type(s) to show is/are    : %s\n",$settings_ref->{handle}->{type}) if $settings_ref->{debug} =~ /True/ ;

	}
	
	# check the header data
	if( $header ) {

		$settings_ref->{handle}->{headerextra} = $header;
		printf("The extra header info is      : %s\n",$settings_ref->{handle}->{headerextra}) if $settings_ref->{debug} =~ /True/ ;
	
	}

	# check the credentials data
	if( $credentials ) {

		# read the credentials from the file
		my $filename = $credentials;
		my $json_text = do {
			open(my $json_fh, "<:encoding(UTF-8)", $filename)  or die("Can't open $filename: $!\n");
			local $/;
			<$json_fh>
		};

		# convert from json and put in correct place 
		my $json = JSON->new;
		$settings_ref->{handle}->{credentials} = $json->decode($json_text);

		printf("The username is               : %s\n",$settings_ref->{handle}->{credentials}->{username}) if $settings_ref->{debug} =~ /True/ ;
		printf("The password is               : %s\n",$settings_ref->{handle}->{credentials}->{password}) if $settings_ref->{debug} =~ /True/ ;
		printf("The base uri is               : %s\n",$settings_ref->{handle}->{credentials}->{baseuri}) if $settings_ref->{debug} =~ /True/ ;
	}

	# Print the message
	if( $message ) {

		print "$message\n";
	};

	# Return the results
	return($returncode);

};

The Result

The result of the automatic generation

GRNET-0000-0000-000A-5-TEST

Manual generation of SUFFIX

Its up to the user to decide the names of the PIDs. You may use

In all examples in this manual we use a UUID generator.