From 015dd6c1b47edc33f663599cc62d45d5d89e7699 Mon Sep 17 00:00:00 2001 From: Daniel Lamb Date: Tue, 8 Dec 2015 00:32:22 -0400 Subject: [PATCH 01/13] Example transaction service. --- services/TransactionService/.gitignore | 3 + services/TransactionService/composer.json | 17 +++++ services/TransactionService/src/index.php | 79 +++++++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 services/TransactionService/.gitignore create mode 100644 services/TransactionService/composer.json create mode 100644 services/TransactionService/src/index.php diff --git a/services/TransactionService/.gitignore b/services/TransactionService/.gitignore new file mode 100644 index 000000000..b0def9af0 --- /dev/null +++ b/services/TransactionService/.gitignore @@ -0,0 +1,3 @@ +composer.lock +composer.phar +vendor diff --git a/services/TransactionService/composer.json b/services/TransactionService/composer.json new file mode 100644 index 000000000..bbe33f609 --- /dev/null +++ b/services/TransactionService/composer.json @@ -0,0 +1,17 @@ +{ + "name": "islandora/transaction-service", + "description": "RESTful service providing transactions in Fedora 4", + "require": { + "islandora/chullo": "^0.0.1", + "silex/silex": "^1.3" + }, + "autoload": { + "psr-4": {"Islandora\\TransactionService\\": "src/"} + }, + "authors": [ + { + "name": "Daniel Lamb", + "email": "daniel@discoverygarden.ca" + } + ] +} diff --git a/services/TransactionService/src/index.php b/services/TransactionService/src/index.php new file mode 100644 index 000000000..9224c677d --- /dev/null +++ b/services/TransactionService/src/index.php @@ -0,0 +1,79 @@ + 'http://127.0.0.1:8080/fcrepo/rest']); + return new Chullo($client); +}; + +$app->post( + "/islandora/transaction", + function (Application $app) { + try { + return new Response($app['fedora']->createTransaction(), 201); + } + catch (ClientException $e) { + $response = $e->getResponse(); + $app->abort($response->getStatusCode(), $response->getReasonPhrase()); + } + } +); + +$app->post( + "/islandora/transaction/{id}/extend", + function (Application $app, $id) { + try { + $app['fedora']->extendTransaction($id); + return new Response("", 204); + } + catch (ClientException $e) { + $response = $e->getResponse(); + $app->abort($response->getStatusCode(), $response->getReasonPhrase()); + } + } +); + +$app->post( + "/islandora/transaction/{id}/commit", + function (Application $app, $id) { + try { + $app['fedora']->commitTransaction($id); + return new Response("", 204); + } + catch (ClientException $e) { + $response = $e->getResponse(); + $app->abort($response->getStatusCode(), $response->getReasonPhrase()); + } + } +); + +$app->post( + "/islandora/transaction/{id}/rollback", + function (Application $app, $id) { + try { + return $app['fedora']->rollbackTransaction($id); + return new Response("", 204); + } + catch (ClientException $e) { + $response = $e->getResponse(); + $app->abort($response->getStatusCode(), $response->getReasonPhrase()); + } + } +); + +$app->run(); From 00c2cf33c15011e63761bb7cc2a8fe735dd423bc Mon Sep 17 00:00:00 2001 From: Daniel Lamb Date: Tue, 8 Dec 2015 11:22:00 -0400 Subject: [PATCH 02/13] Updating PR to use static factory function for Chullo. --- services/TransactionService/src/index.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/services/TransactionService/src/index.php b/services/TransactionService/src/index.php index 9224c677d..da9622e9d 100644 --- a/services/TransactionService/src/index.php +++ b/services/TransactionService/src/index.php @@ -4,7 +4,6 @@ require_once __DIR__.'/../vendor/autoload.php'; -use GuzzleHttp\Client; use GuzzleHttp\Exception\ClientException; use Islandora\Chullo\Chullo; use Silex\Application; @@ -17,8 +16,7 @@ $app['debug'] = true; $app['fedora'] = function () use ($app) { - $client = new Client(['base_uri' => 'http://127.0.0.1:8080/fcrepo/rest']); - return new Chullo($client); + return Chullo::create('http://127.0.0.1:8080/fcrepo/rest'); }; $app->post( From d3d34c838b537d94345dc9998923d794d5576813 Mon Sep 17 00:00:00 2001 From: Daniel Lamb Date: Fri, 11 Dec 2015 09:29:23 -0400 Subject: [PATCH 03/13] Using view handler to convert PSR-7 to Symfony responses. Using the FedoraApi class from Chullo. --- services/TransactionService/composer.json | 8 +++- services/TransactionService/src/index.php | 47 +++++++---------------- 2 files changed, 21 insertions(+), 34 deletions(-) diff --git a/services/TransactionService/composer.json b/services/TransactionService/composer.json index bbe33f609..f5c5fa76e 100644 --- a/services/TransactionService/composer.json +++ b/services/TransactionService/composer.json @@ -1,8 +1,14 @@ { "name": "islandora/transaction-service", "description": "RESTful service providing transactions in Fedora 4", + "repositories": [ + { + "type": "vcs", + "url": "/Users/danny/Git/chullo" + } + ], "require": { - "islandora/chullo": "^0.0.1", + "islandora/chullo": "dev-master", "silex/silex": "^1.3" }, "autoload": { diff --git a/services/TransactionService/src/index.php b/services/TransactionService/src/index.php index da9622e9d..a4d8baf87 100644 --- a/services/TransactionService/src/index.php +++ b/services/TransactionService/src/index.php @@ -5,9 +5,10 @@ require_once __DIR__.'/../vendor/autoload.php'; use GuzzleHttp\Exception\ClientException; -use Islandora\Chullo\Chullo; +use Islandora\Chullo\FedoraApi; use Silex\Application; use Symfony\Component\HttpFoundation\Response; +use Psr\Http\Message\ResponseInterface; date_default_timezone_set('UTC'); @@ -16,61 +17,41 @@ $app['debug'] = true; $app['fedora'] = function () use ($app) { - return Chullo::create('http://127.0.0.1:8080/fcrepo/rest'); + return FedoraApi::create('http://127.0.0.1:8080/fcrepo/rest'); }; +/** + * Convert returned Guzzle responses to Symfony responses. + */ +$app->view(function (ResponseInterface $psr7) { + return new Response($psr7->getBody(), $psr7->getStatusCode(), $psr7->getHeaders()); +}); + $app->post( "/islandora/transaction", function (Application $app) { - try { - return new Response($app['fedora']->createTransaction(), 201); - } - catch (ClientException $e) { - $response = $e->getResponse(); - $app->abort($response->getStatusCode(), $response->getReasonPhrase()); - } + return $app['fedora']->createTransaction(); } ); $app->post( "/islandora/transaction/{id}/extend", function (Application $app, $id) { - try { - $app['fedora']->extendTransaction($id); - return new Response("", 204); - } - catch (ClientException $e) { - $response = $e->getResponse(); - $app->abort($response->getStatusCode(), $response->getReasonPhrase()); - } + return $app['fedora']->extendTransaction($id); } ); $app->post( "/islandora/transaction/{id}/commit", function (Application $app, $id) { - try { - $app['fedora']->commitTransaction($id); - return new Response("", 204); - } - catch (ClientException $e) { - $response = $e->getResponse(); - $app->abort($response->getStatusCode(), $response->getReasonPhrase()); - } + return $app['fedora']->commitTransaction($id); } ); $app->post( "/islandora/transaction/{id}/rollback", function (Application $app, $id) { - try { - return $app['fedora']->rollbackTransaction($id); - return new Response("", 204); - } - catch (ClientException $e) { - $response = $e->getResponse(); - $app->abort($response->getStatusCode(), $response->getReasonPhrase()); - } + return $app['fedora']->rollbackTransaction($id); } ); From b7a51463bc826769e529e19d519c7c2f0adb85d0 Mon Sep 17 00:00:00 2001 From: DiegoPino Date: Mon, 14 Dec 2015 16:37:06 -0300 Subject: [PATCH 04/13] Work in progress for Resource Services Depends on Chullo fixes at https://github.com/DiegoPino/chullo/tree/api --- services/ResourceService/.gitignore | 1 + services/ResourceService/composer.json | 26 + services/ResourceService/composer.lock | 1150 +++++++++++++++++ services/ResourceService/src/index.php | 81 ++ .../templates/getResourceByUUIDfromTS.sparql | 5 + services/TransactionService/composer.json | 2 +- 6 files changed, 1264 insertions(+), 1 deletion(-) create mode 100644 services/ResourceService/.gitignore create mode 100644 services/ResourceService/composer.json create mode 100644 services/ResourceService/composer.lock create mode 100644 services/ResourceService/src/index.php create mode 100644 services/ResourceService/templates/getResourceByUUIDfromTS.sparql diff --git a/services/ResourceService/.gitignore b/services/ResourceService/.gitignore new file mode 100644 index 000000000..48b8bf907 --- /dev/null +++ b/services/ResourceService/.gitignore @@ -0,0 +1 @@ +vendor/ diff --git a/services/ResourceService/composer.json b/services/ResourceService/composer.json new file mode 100644 index 000000000..36653ec10 --- /dev/null +++ b/services/ResourceService/composer.json @@ -0,0 +1,26 @@ +{ + "name": "islandora/resource-service", + "description": "RESTful service providing resources in Fedora 4", + "repositories": [ + { + "type": "vcs", + "url": "/Users/dpino/Desktop/Development/ISLANDORAWORK/CLAW_MICRO/chullo" + } + ], + "require": { + "islandora/chullo": "dev-api", + "silex/silex": "^1.3", + "symfony/config": "^3.0", + "twig/twig": "^1.23", + "symfony/psr-http-message-bridge": "^0.2.0" + }, + "autoload": { + "psr-4": {"Islandora\\ResourceService\\": "src/"} + }, + "authors": [ + { + "name": "Diego Pino Navarro", + "email": "dpino@krayon.cl" + } + ] +} diff --git a/services/ResourceService/composer.lock b/services/ResourceService/composer.lock new file mode 100644 index 000000000..2b9aff280 --- /dev/null +++ b/services/ResourceService/composer.lock @@ -0,0 +1,1150 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "726c84778cf8771ea85150f2139b5c1c", + "content-hash": "5cd13cdb32f435a17777da8019399d72", + "packages": [ + { + "name": "easyrdf/easyrdf", + "version": "0.9.0", + "source": { + "type": "git", + "url": "https://github.com/njh/easyrdf.git", + "reference": "bb9fd99768d23af0c5b7b55cec5baddc201272b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/njh/easyrdf/zipball/bb9fd99768d23af0c5b7b55cec5baddc201272b8", + "reference": "bb9fd99768d23af0c5b7b55cec5baddc201272b8", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "ext-pcre": "*", + "php": ">=5.2.8" + }, + "require-dev": { + "phpunit/phpunit": "~3.5", + "sami/sami": "~1.4", + "squizlabs/php_codesniffer": "~1.4.3" + }, + "suggest": { + "ml/json-ld": "~1.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "EasyRdf_": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nicholas Humfrey", + "email": "njh@aelius.com", + "homepage": "http://www.aelius.com/njh/", + "role": "Developer" + }, + { + "name": "Alexey Zakhlestin", + "email": "indeyets@gmail.com", + "role": "Developer" + } + ], + "description": "EasyRdf is a PHP library designed to make it easy to consume and produce RDF.", + "homepage": "http://www.easyrdf.org/", + "keywords": [ + "Linked Data", + "RDF", + "Semantic Web", + "Turtle", + "rdfa", + "sparql" + ], + "time": "2014-11-07 18:02:16" + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.1.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "66fd14b4d0b8f2389eaf37c5458608c7cb793a81" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/66fd14b4d0b8f2389eaf37c5458608c7cb793a81", + "reference": "66fd14b4d0b8f2389eaf37c5458608c7cb793a81", + "shasum": "" + }, + "require": { + "guzzlehttp/promises": "~1.0", + "guzzlehttp/psr7": "~1.1", + "php": ">=5.5.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "~4.0", + "psr/log": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.1-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2015-09-08 17:36:26" + }, + { + "name": "guzzlehttp/promises", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/b1e1c0d55f8083c71eda2c28c12a228d708294ea", + "reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea", + "shasum": "" + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "time": "2015-10-15 22:28:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "4d0bdbe1206df7440219ce14c972aa57cc5e4982" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/4d0bdbe1206df7440219ce14c972aa57cc5e4982", + "reference": "4d0bdbe1206df7440219ce14c972aa57cc5e4982", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "PSR-7 message implementation", + "keywords": [ + "http", + "message", + "stream", + "uri" + ], + "time": "2015-11-03 01:34:55" + }, + { + "name": "islandora/chullo", + "version": "dev-api", + "source": { + "type": "git", + "url": "/Users/dpino/Desktop/Development/ISLANDORAWORK/CLAW_MICRO/chullo", + "reference": "4d2e2bea4b2f1b1cc54d9b0ee5c49744031f810c" + }, + "require": { + "easyrdf/easyrdf": "0.9.0", + "guzzlehttp/guzzle": "6.1.0", + "ml/json-ld": "1.0.3", + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Islandora\\Chullo\\": "src/" + } + }, + "license": [ + "GPLv3" + ], + "authors": [ + { + "name": "Islandora Foundation", + "email": "community@islandora.ca", + "role": "Owner" + }, + { + "name": "Daniel Lamb", + "email": "daniel@discoverygarden.ca", + "role": "Maintainer" + }, + { + "name": "Nick Ruest", + "email": "ruestn@gmail.com", + "role": "Maintainer" + } + ], + "description": "A PHP client for interacting with a Fedora 4 server.", + "homepage": "https://github.com/islandora-claw/chullo", + "support": { + "issues": "https://github.com/islandora-claw/chullo/issues", + "irc": "irc://irc.freenode.net/islandora" + }, + "time": "2015-12-14 13:59:22" + }, + { + "name": "ml/iri", + "version": "1.1.4", + "target-dir": "ML/IRI", + "source": { + "type": "git", + "url": "https://github.com/lanthaler/IRI.git", + "reference": "cbd44fa913e00ea624241b38cefaa99da8d71341" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lanthaler/IRI/zipball/cbd44fa913e00ea624241b38cefaa99da8d71341", + "reference": "cbd44fa913e00ea624241b38cefaa99da8d71341", + "shasum": "" + }, + "require": { + "lib-pcre": ">=4.0", + "php": ">=5.3.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "ML\\IRI": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Markus Lanthaler", + "email": "mail@markus-lanthaler.com", + "homepage": "http://www.markus-lanthaler.com", + "role": "Developer" + } + ], + "description": "IRI handling for PHP", + "homepage": "http://www.markus-lanthaler.com", + "keywords": [ + "URN", + "iri", + "uri", + "url" + ], + "time": "2014-01-21 13:43:39" + }, + { + "name": "ml/json-ld", + "version": "1.0.3", + "target-dir": "ML/JsonLD", + "source": { + "type": "git", + "url": "https://github.com/lanthaler/JsonLD.git", + "reference": "10a03f7dec0f4a7db6b2e6e6230cdfb7cce562a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lanthaler/JsonLD/zipball/10a03f7dec0f4a7db6b2e6e6230cdfb7cce562a2", + "reference": "10a03f7dec0f4a7db6b2e6e6230cdfb7cce562a2", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ml/iri": ">=1.1.1", + "php": ">=5.3.0" + }, + "require-dev": { + "json-ld/tests": "@dev" + }, + "type": "library", + "autoload": { + "psr-0": { + "ML\\JsonLD": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Markus Lanthaler", + "email": "mail@markus-lanthaler.com", + "homepage": "http://www.markus-lanthaler.com", + "role": "Developer" + } + ], + "description": "JSON-LD Processor for PHP", + "homepage": "http://www.markus-lanthaler.com", + "keywords": [ + "JSON-LD", + "jsonld" + ], + "time": "2014-09-15 10:41:19" + }, + { + "name": "pimple/pimple", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/silexphp/Pimple.git", + "reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/silexphp/Pimple/zipball/2019c145fe393923f3441b23f29bbdfaa5c58c4d", + "reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-0": { + "Pimple": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Pimple is a simple Dependency Injection Container for PHP 5.3", + "homepage": "http://pimple.sensiolabs.org", + "keywords": [ + "container", + "dependency injection" + ], + "time": "2013-11-22 08:30:29" + }, + { + "name": "psr/http-message", + "version": "1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", + "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2015-05-04 20:22:00" + }, + { + "name": "psr/log", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", + "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-0": { + "Psr\\Log\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2012-12-21 11:40:51" + }, + { + "name": "silex/silex", + "version": "v1.3.4", + "source": { + "type": "git", + "url": "https://github.com/silexphp/Silex.git", + "reference": "d6de62716fcda76084f3015165125f30b1563517" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/silexphp/Silex/zipball/d6de62716fcda76084f3015165125f30b1563517", + "reference": "d6de62716fcda76084f3015165125f30b1563517", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "pimple/pimple": "~1.0", + "symfony/event-dispatcher": "~2.3|3.0.*", + "symfony/http-foundation": "~2.3|3.0.*", + "symfony/http-kernel": "~2.3|3.0.*", + "symfony/routing": "~2.3|3.0.*" + }, + "require-dev": { + "doctrine/dbal": "~2.2", + "monolog/monolog": "^1.4.1", + "swiftmailer/swiftmailer": "~5", + "symfony/browser-kit": "~2.3|3.0.*", + "symfony/config": "~2.3|3.0.*", + "symfony/css-selector": "~2.3|3.0.*", + "symfony/debug": "~2.3|3.0.*", + "symfony/dom-crawler": "~2.3|3.0.*", + "symfony/finder": "~2.3|3.0.*", + "symfony/form": "~2.3|3.0.*", + "symfony/locale": "~2.3|3.0.*", + "symfony/monolog-bridge": "~2.3|3.0.*", + "symfony/options-resolver": "~2.3|3.0.*", + "symfony/phpunit-bridge": "~2.7", + "symfony/process": "~2.3|3.0.*", + "symfony/security": "~2.3|3.0.*", + "symfony/serializer": "~2.3|3.0.*", + "symfony/translation": "~2.3|3.0.*", + "symfony/twig-bridge": "~2.3|3.0.*", + "symfony/validator": "~2.3|3.0.*", + "twig/twig": "~1.8|~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Silex\\": "src/Silex" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + } + ], + "description": "The PHP micro-framework based on the Symfony Components", + "homepage": "http://silex.sensiolabs.org", + "keywords": [ + "microframework" + ], + "time": "2015-09-15 06:53:42" + }, + { + "name": "symfony/config", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "40bae8658dbbb500ebc19aa9fde22dc4295fc290" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/40bae8658dbbb500ebc19aa9fde22dc4295fc290", + "reference": "40bae8658dbbb500ebc19aa9fde22dc4295fc290", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/filesystem": "~2.8|~3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Config Component", + "homepage": "https://symfony.com", + "time": "2015-11-02 20:34:04" + }, + { + "name": "symfony/debug", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "0623b00095f0833412ee6f92f421e9adf4c7e113" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/0623b00095f0833412ee6f92f421e9adf4c7e113", + "reference": "0623b00095f0833412ee6f92f421e9adf4c7e113", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "psr/log": "~1.0" + }, + "conflict": { + "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" + }, + "require-dev": { + "symfony/class-loader": "~2.8|~3.0", + "symfony/http-kernel": "~2.8|~3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Debug\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Debug Component", + "homepage": "https://symfony.com", + "time": "2015-11-27 05:46:53" + }, + { + "name": "symfony/event-dispatcher", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "d36355e026905fa5229e1ed7b4e9eda2e67adfcf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d36355e026905fa5229e1ed7b4e9eda2e67adfcf", + "reference": "d36355e026905fa5229e1ed7b4e9eda2e67adfcf", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.8|~3.0", + "symfony/dependency-injection": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/stopwatch": "~2.8|~3.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "time": "2015-10-30 23:35:59" + }, + { + "name": "symfony/filesystem", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "692d98d813e4ef314b9c22775c86ddbeb0f44884" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/692d98d813e4ef314b9c22775c86ddbeb0f44884", + "reference": "692d98d813e4ef314b9c22775c86ddbeb0f44884", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "https://symfony.com", + "time": "2015-11-23 10:41:47" + }, + { + "name": "symfony/http-foundation", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "1563f784900958afdb584ca82a072c578ed8a929" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/1563f784900958afdb584ca82a072c578ed8a929", + "reference": "1563f784900958afdb584ca82a072c578ed8a929", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "require-dev": { + "symfony/expression-language": "~2.8|~3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony HttpFoundation Component", + "homepage": "https://symfony.com", + "time": "2015-11-27 14:30:17" + }, + { + "name": "symfony/http-kernel", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "2f7071c25cae37b79be6d9ea1c43c1035d8c6b06" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/2f7071c25cae37b79be6d9ea1c43c1035d8c6b06", + "reference": "2f7071c25cae37b79be6d9ea1c43c1035d8c6b06", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "psr/log": "~1.0", + "symfony/debug": "~2.8|~3.0", + "symfony/event-dispatcher": "~2.8|~3.0", + "symfony/http-foundation": "~2.8|~3.0" + }, + "conflict": { + "symfony/config": "<2.8" + }, + "require-dev": { + "symfony/browser-kit": "~2.8|~3.0", + "symfony/class-loader": "~2.8|~3.0", + "symfony/config": "~2.8|~3.0", + "symfony/console": "~2.8|~3.0", + "symfony/css-selector": "~2.8|~3.0", + "symfony/dependency-injection": "~2.8|~3.0", + "symfony/dom-crawler": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/finder": "~2.8|~3.0", + "symfony/process": "~2.8|~3.0", + "symfony/routing": "~2.8|~3.0", + "symfony/stopwatch": "~2.8|~3.0", + "symfony/templating": "~2.8|~3.0", + "symfony/translation": "~2.8|~3.0", + "symfony/var-dumper": "~2.8|~3.0" + }, + "suggest": { + "symfony/browser-kit": "", + "symfony/class-loader": "", + "symfony/config": "", + "symfony/console": "", + "symfony/dependency-injection": "", + "symfony/finder": "", + "symfony/var-dumper": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony HttpKernel Component", + "homepage": "https://symfony.com", + "time": "2015-11-30 20:59:24" + }, + { + "name": "symfony/psr-http-message-bridge", + "version": "v0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/psr-http-message-bridge.git", + "reference": "dc7e308e1dc2898a46776e2221a643cb08315453" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/dc7e308e1dc2898a46776e2221a643cb08315453", + "reference": "dc7e308e1dc2898a46776e2221a643cb08315453", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "psr/http-message": "~1.0", + "symfony/http-foundation": "~2.3|~3.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7|~3.0" + }, + "suggest": { + "zendframework/zend-diactoros": "To use the Zend Diactoros factory" + }, + "type": "symfony-bridge", + "autoload": { + "psr-4": { + "Symfony\\Bridge\\PsrHttpMessage\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "PSR HTTP message bridge", + "homepage": "http://symfony.com", + "keywords": [ + "http", + "http-message", + "psr-7" + ], + "time": "2015-05-29 17:57:12" + }, + { + "name": "symfony/routing", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "252014dfa4685e80f9216ae4b7d78b1a50dd55c2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/252014dfa4685e80f9216ae4b7d78b1a50dd55c2", + "reference": "252014dfa4685e80f9216ae4b7d78b1a50dd55c2", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "conflict": { + "symfony/config": "<2.8" + }, + "require-dev": { + "doctrine/annotations": "~1.0", + "doctrine/common": "~2.2", + "psr/log": "~1.0", + "symfony/config": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/http-foundation": "~2.8|~3.0", + "symfony/yaml": "~2.8|~3.0" + }, + "suggest": { + "doctrine/annotations": "For using the annotation loader", + "symfony/config": "For using the all-in-one router or any loader", + "symfony/dependency-injection": "For loading routes from a service", + "symfony/expression-language": "For using expression matching", + "symfony/yaml": "For using the YAML loader" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Routing Component", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "time": "2015-11-26 07:02:09" + }, + { + "name": "twig/twig", + "version": "v1.23.1", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "d9b6333ae8dd2c8e3fd256e127548def0bc614c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/d9b6333ae8dd2c8e3fd256e127548def0bc614c6", + "reference": "d9b6333ae8dd2c8e3fd256e127548def0bc614c6", + "shasum": "" + }, + "require": { + "php": ">=5.2.7" + }, + "require-dev": { + "symfony/debug": "~2.7", + "symfony/phpunit-bridge": "~2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.23-dev" + } + }, + "autoload": { + "psr-0": { + "Twig_": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" + }, + { + "name": "Twig Team", + "homepage": "http://twig.sensiolabs.org/contributors", + "role": "Contributors" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "http://twig.sensiolabs.org", + "keywords": [ + "templating" + ], + "time": "2015-11-05 12:49:06" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": { + "islandora/chullo": 20 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/services/ResourceService/src/index.php b/services/ResourceService/src/index.php new file mode 100644 index 000000000..de62680c9 --- /dev/null +++ b/services/ResourceService/src/index.php @@ -0,0 +1,81 @@ +register(new \Silex\Provider\TwigServiceProvider(), array( + 'twig.path' => __DIR__.'/../templates', +)); + +$app['twig'] = $app->share($app->extend('twig', function($twig, $app) { + return $twig; +})); + +$app['fedora'] = $app->share(function() { + return Chullo::create('http://localhost:8080/rest'); +}); + +$app['triplestore'] = $app->share(function() { + return TriplestoreClient::create('http://localhost:9999/bigdata/sparql'); +}); +$app['data.resourcepath'] = NULL; + +/** + * Convert returned Guzzle responses to Symfony responses. + */ +$app->view(function (ResponseInterface $psr7) { + return new Response($psr7->getBody(), $psr7->getStatusCode(), $psr7->getHeaders()); +}); + +$app->get("/islandora/resource/{uuid}",function (\Silex\Application $app, Request $request, $uuid) { + if (NULL === $app['data.resourcepath']) { + $app->abort(404, 'Failed getting resource Path for {$uuid}'); + } + $tx = $request->query->get('tx',""); + $response = $app['fedora']->getResource($app->escape($app['data.resourcepath']), $request->headers->all(), $tx); + if (NULL === $response ) + { + $app->abort(404, 'Failed getting resource from Fedora4'); + } + return $response; +})->before(function (Request $request) use ($app) { + // In case the request was made by a browser, avoid + // returning the whole Fedora4 API Rest interface page. + if (0 === strpos($request->headers->get('Accept'),'text/html')) { + $request->headers->set('Accept', 'text/turtle', TRUE); + } + $sparql_query = $app['twig']->render('getResourceByUUIDfromTS.sparql', array( + 'uuid' => $request->attributes->get('uuid'), + )); + + $sparql_result = $app['triplestore']->query($sparql_query); + foreach ($sparql_result as $triple) { + $app['data.resourcepath'] = $triple->s->getUri(); + } + +}); + +$app->after(function (Request $request, Response $response, \Silex\Application $app) { +}); + + + +$app->run(); diff --git a/services/ResourceService/templates/getResourceByUUIDfromTS.sparql b/services/ResourceService/templates/getResourceByUUIDfromTS.sparql new file mode 100644 index 000000000..b8fe9a70e --- /dev/null +++ b/services/ResourceService/templates/getResourceByUUIDfromTS.sparql @@ -0,0 +1,5 @@ +PREFIX nfo: +PREFIX rdf: +SELECT ?s WHERE { + ?s nfo:uuid "{{uuid}}"^^ . +} diff --git a/services/TransactionService/composer.json b/services/TransactionService/composer.json index f5c5fa76e..e944e0231 100644 --- a/services/TransactionService/composer.json +++ b/services/TransactionService/composer.json @@ -4,7 +4,7 @@ "repositories": [ { "type": "vcs", - "url": "/Users/danny/Git/chullo" + "url": "/Users/dpino/Desktop/Development/ISLANDORAWORK/CLAW_MICRO/chullo" } ], "require": { From 92d04ca04373bf85c42f5e39f9301afedb102bde Mon Sep 17 00:00:00 2001 From: DiegoPino Date: Mon, 14 Dec 2015 17:46:53 -0300 Subject: [PATCH 05/13] uuid check + child resource for ResourceService for get route: assuming it's running in 8181 (example php -S localhost:8181 -t src src/index.php ) then http://localhost:8181/islandora/resource/7ef68f6f-72ab-4708-b0f4-8ec1f07 cd580 will get the resource for a resource that has nfo:uuid -> 7ef68f6f-72ab-4708-b0f4-8ec1f07cd580 in the triple store and http://localhost:8181/islandora/resource/7ef68f6f-72ab-4708-b0f4-8ec1f07 cd580/OBJ will get the child resource for that one (in this case binary) Accepts also a ?tx=transactionid * if the transactionid does not exist if fails with 404 * if uuid is not uuid then it fails with 404 * if resource path is not in triple store if fails with 404 --- services/ResourceService/src/index.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/services/ResourceService/src/index.php b/services/ResourceService/src/index.php index de62680c9..6b9f30ea2 100644 --- a/services/ResourceService/src/index.php +++ b/services/ResourceService/src/index.php @@ -44,19 +44,24 @@ $app->view(function (ResponseInterface $psr7) { return new Response($psr7->getBody(), $psr7->getStatusCode(), $psr7->getHeaders()); }); - -$app->get("/islandora/resource/{uuid}",function (\Silex\Application $app, Request $request, $uuid) { +/** + * resource GET route. takes an UUID as first value to match, optional a child resource + */ +$app->get("/islandora/resource/{uuid}/{child}",function (\Silex\Application $app, Request $request, $uuid, $child) { if (NULL === $app['data.resourcepath']) { $app->abort(404, 'Failed getting resource Path for {$uuid}'); } $tx = $request->query->get('tx',""); - $response = $app['fedora']->getResource($app->escape($app['data.resourcepath']), $request->headers->all(), $tx); + $response = $app['fedora']->getResource($app->escape($app['data.resourcepath']) . '/' . $child, $request->headers->all(), $tx); if (NULL === $response ) { $app->abort(404, 'Failed getting resource from Fedora4'); } return $response; -})->before(function (Request $request) use ($app) { +}) +->value('child',"") +->assert('uuid','([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})') +->before(function (Request $request) use ($app) { // In case the request was made by a browser, avoid // returning the whole Fedora4 API Rest interface page. if (0 === strpos($request->headers->get('Accept'),'text/html')) { From f6baff1441e1cd1f387e9aa0d113d6840c4e5ff4 Mon Sep 17 00:00:00 2001 From: DiegoPino Date: Mon, 14 Dec 2015 18:00:30 -0300 Subject: [PATCH 06/13] Adds metadata options to ResourceService get route Main route for getting a resource accepts also a metadata argument localhost:8181/islandora/resource/7ef68f6f-72ab-4708-b0f4-8ec1f07cd580/O BJ/?metadata=true In case of binary it will return triples instead of the binary resource In case of an container i will get you the RDF (basically ignoring this option) --- services/ResourceService/src/index.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/ResourceService/src/index.php b/services/ResourceService/src/index.php index 6b9f30ea2..494206032 100644 --- a/services/ResourceService/src/index.php +++ b/services/ResourceService/src/index.php @@ -52,7 +52,8 @@ $app->abort(404, 'Failed getting resource Path for {$uuid}'); } $tx = $request->query->get('tx',""); - $response = $app['fedora']->getResource($app->escape($app['data.resourcepath']) . '/' . $child, $request->headers->all(), $tx); + $metadata = $request->query->get('metadata',FALSE) ? '/fcr:metadata' : ""; + $response = $app['fedora']->getResource($app->escape($app['data.resourcepath']) . '/' . $child . $metadata , $request->headers->all(), $tx); if (NULL === $response ) { $app->abort(404, 'Failed getting resource from Fedora4'); From 86bd39b5e33eb6bb1e77aa35d6cbdc8d032989cf Mon Sep 17 00:00:00 2001 From: DiegoPino Date: Thu, 17 Dec 2015 13:39:07 -0300 Subject: [PATCH 07/13] POST resource creation working --- services/ResourceService/composer.lock | 4 +- services/ResourceService/src/index.php | 55 +++++++++++++++++++------- 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/services/ResourceService/composer.lock b/services/ResourceService/composer.lock index 2b9aff280..00f04f8f5 100644 --- a/services/ResourceService/composer.lock +++ b/services/ResourceService/composer.lock @@ -246,7 +246,7 @@ "source": { "type": "git", "url": "/Users/dpino/Desktop/Development/ISLANDORAWORK/CLAW_MICRO/chullo", - "reference": "4d2e2bea4b2f1b1cc54d9b0ee5c49744031f810c" + "reference": "f8a03d7cd4bff0712c4e5e925d70108d03d17829" }, "require": { "easyrdf/easyrdf": "0.9.0", @@ -289,7 +289,7 @@ "issues": "https://github.com/islandora-claw/chullo/issues", "irc": "irc://irc.freenode.net/islandora" }, - "time": "2015-12-14 13:59:22" + "time": "2015-12-16 17:32:51" }, { "name": "ml/iri", diff --git a/services/ResourceService/src/index.php b/services/ResourceService/src/index.php index 494206032..4fcd54aa6 100644 --- a/services/ResourceService/src/index.php +++ b/services/ResourceService/src/index.php @@ -36,8 +36,25 @@ $app['triplestore'] = $app->share(function() { return TriplestoreClient::create('http://localhost:9999/bigdata/sparql'); }); + $app['data.resourcepath'] = NULL; +$getPathFromTriple = function (Request $request,\Silex\Application $app) { + // In case the request was made by a browser, avoid + // returning the whole Fedora4 API Rest interface page. + if (0 === strpos($request->headers->get('Accept'),'text/html')) { + $request->headers->set('Accept', 'text/turtle', TRUE); + } + $sparql_query = $app['twig']->render('getResourceByUUIDfromTS.sparql', array( + 'uuid' => $request->attributes->get('uuid'), + )); + + $sparql_result = $app['triplestore']->query($sparql_query); + foreach ($sparql_result as $triple) { + $app['data.resourcepath'] = $triple->s->getUri(); + } +}; + /** * Convert returned Guzzle responses to Symfony responses. */ @@ -46,6 +63,8 @@ }); /** * resource GET route. takes an UUID as first value to match, optional a child resource + * takes 'rx' and/or 'metadata' as query arguments + * @see https://wiki.duraspace.org/display/FEDORA40/RESTful+HTTP+API#RESTfulHTTPAPI-GETRetrievethecontentoftheresource */ $app->get("/islandora/resource/{uuid}/{child}",function (\Silex\Application $app, Request $request, $uuid, $child) { if (NULL === $app['data.resourcepath']) { @@ -62,22 +81,28 @@ }) ->value('child',"") ->assert('uuid','([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})') -->before(function (Request $request) use ($app) { - // In case the request was made by a browser, avoid - // returning the whole Fedora4 API Rest interface page. - if (0 === strpos($request->headers->get('Accept'),'text/html')) { - $request->headers->set('Accept', 'text/turtle', TRUE); - } - $sparql_query = $app['twig']->render('getResourceByUUIDfromTS.sparql', array( - 'uuid' => $request->attributes->get('uuid'), - )); - - $sparql_result = $app['triplestore']->query($sparql_query); - foreach ($sparql_result as $triple) { - $app['data.resourcepath'] = $triple->s->getUri(); - } +->before($getPathFromTriple); -}); +/** + * resource POST route. takes an UUID for the parent resource as first value to match + * takes rx and/or $checksum as query arguments + * @see https://wiki.duraspace.org/display/FEDORA40/RESTful+HTTP+API#RESTfulHTTPAPI-BluePOSTCreatenewresourceswithinaLDPcontainer + */ +$app->post("/islandora/resource/{uuid}/{checksum}",function (\Silex\Application $app, Request $request, $uuid, $checksum) { + if (NULL === $app['data.resourcepath']) { + $app->abort(404, 'Failed getting resource Path for {$uuid}'); + } + $tx = $request->query->get('tx',""); + $response = $app['fedora']->createResource($app->escape($app['data.resourcepath']), $request->getContent(), $request->headers->all(), $tx, $checksum); + if (NULL === $response ) + { + $app->abort(404, 'Failed creating resource from Fedora4'); + } + return $response; +}) +->value('checksum',"") +->assert('uuid','([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})') +->before($getPathFromTriple); $app->after(function (Request $request, Response $response, \Silex\Application $app) { }); From 89a09cce872d34883b0131a4edae8a8c1279d19e Mon Sep 17 00:00:00 2001 From: DiegoPino Date: Thu, 17 Dec 2015 18:31:57 -0300 Subject: [PATCH 08/13] PUT resource route working Also moved some route parameters to query arguments (checksum) in all routes: tx ,checksum and metadata (depending on what is used in each route) --- services/ResourceService/src/index.php | 36 ++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/services/ResourceService/src/index.php b/services/ResourceService/src/index.php index 4fcd54aa6..fb5bbc982 100644 --- a/services/ResourceService/src/index.php +++ b/services/ResourceService/src/index.php @@ -62,8 +62,8 @@ return new Response($psr7->getBody(), $psr7->getStatusCode(), $psr7->getHeaders()); }); /** - * resource GET route. takes an UUID as first value to match, optional a child resource - * takes 'rx' and/or 'metadata' as query arguments + * resource GET route. takes an UUID as first value to match, optional a child resource path + * takes 'rx' and/or 'metadata' as optional query arguments * @see https://wiki.duraspace.org/display/FEDORA40/RESTful+HTTP+API#RESTfulHTTPAPI-GETRetrievethecontentoftheresource */ $app->get("/islandora/resource/{uuid}/{child}",function (\Silex\Application $app, Request $request, $uuid, $child) { @@ -85,14 +85,15 @@ /** * resource POST route. takes an UUID for the parent resource as first value to match - * takes rx and/or $checksum as query arguments + * takes 'rx' and/or 'checksum' as optional query arguments * @see https://wiki.duraspace.org/display/FEDORA40/RESTful+HTTP+API#RESTfulHTTPAPI-BluePOSTCreatenewresourceswithinaLDPcontainer */ -$app->post("/islandora/resource/{uuid}/{checksum}",function (\Silex\Application $app, Request $request, $uuid, $checksum) { +$app->post("/islandora/resource/{uuid}",function (\Silex\Application $app, Request $request, $uuid, $checksum) { if (NULL === $app['data.resourcepath']) { $app->abort(404, 'Failed getting resource Path for {$uuid}'); } $tx = $request->query->get('tx',""); + $checksum = $request->query->get('checksum',""); $response = $app['fedora']->createResource($app->escape($app['data.resourcepath']), $request->getContent(), $request->headers->all(), $tx, $checksum); if (NULL === $response ) { @@ -100,7 +101,32 @@ } return $response; }) -->value('checksum',"") +->assert('uuid','([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})') +->before($getPathFromTriple); + +$app->after(function (Request $request, Response $response, \Silex\Application $app) { +}); + +/** + * resource PUT route. takes an UUID for the resource to be update/created as first value to match, + * optional a Child resource relative path + * takes 'rx' and/or 'checksum' as query arguments + * @see https://wiki.duraspace.org/display/FEDORA40/RESTful+HTTP+API#RESTfulHTTPAPI-BluePOSTCreatenewresourceswithinaLDPcontainer + */ +$app->put("/islandora/resource/{uuid}/{child}",function (\Silex\Application $app, Request $request, $uuid, $child) { + if (NULL === $app['data.resourcepath']) { + $app->abort(404, 'Failed getting resource Path for {$uuid}'); + } + $tx = $request->query->get('tx',""); + $checksum = $request->query->get('checksum',""); + $response = $app['fedora']->saveResource($app->escape($app['data.resourcepath']) . '/' . $child, $request->getContent(), $request->headers->all(), $tx, $checksum); + if (NULL === $response ) + { + $app->abort(404, 'Failed putting resource into Fedora4'); + } + return $response; +}) +->value('child',"") ->assert('uuid','([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})') ->before($getPathFromTriple); From 2a0efc31714ca418ffd26b8b94536b4a1183548c Mon Sep 17 00:00:00 2001 From: DiegoPino Date: Fri, 18 Dec 2015 12:02:20 -0300 Subject: [PATCH 09/13] PATCH route added Did also a lot of coding cleanup. Not sure if the Symphony coding standard as base is good enough? Moved the ->abort for non existing resource path in triple store into the middleware. --- services/ResourceService/src/index.php | 113 ++++++++++++++----------- 1 file changed, 65 insertions(+), 48 deletions(-) diff --git a/services/ResourceService/src/index.php b/services/ResourceService/src/index.php index fb5bbc982..27050c78b 100644 --- a/services/ResourceService/src/index.php +++ b/services/ResourceService/src/index.php @@ -22,18 +22,21 @@ $app['debug'] = true; $app->register(new \Silex\Provider\TwigServiceProvider(), array( - 'twig.path' => __DIR__.'/../templates', + 'twig.path' => __DIR__.'/../templates', )); $app['twig'] = $app->share($app->extend('twig', function($twig, $app) { - return $twig; + + return $twig; })); $app['fedora'] = $app->share(function() { - return Chullo::create('http://localhost:8080/rest'); + + return Chullo::create('http://localhost:8080/rest'); }); $app['triplestore'] = $app->share(function() { + return TriplestoreClient::create('http://localhost:9999/bigdata/sparql'); }); @@ -42,41 +45,46 @@ $getPathFromTriple = function (Request $request,\Silex\Application $app) { // In case the request was made by a browser, avoid // returning the whole Fedora4 API Rest interface page. - if (0 === strpos($request->headers->get('Accept'),'text/html')) { - $request->headers->set('Accept', 'text/turtle', TRUE); - } - $sparql_query = $app['twig']->render('getResourceByUUIDfromTS.sparql', array( - 'uuid' => $request->attributes->get('uuid'), - )); + if (0 === strpos($request->headers->get('Accept'),'text/html')) { + $request->headers->set('Accept', 'text/turtle', TRUE); + } + $sparql_query = $app['twig']->render('getResourceByUUIDfromTS.sparql', array( + 'uuid' => $request->attributes->get('uuid'), + )); - $sparql_result = $app['triplestore']->query($sparql_query); - foreach ($sparql_result as $triple) { - $app['data.resourcepath'] = $triple->s->getUri(); - } + $sparql_result = $app['triplestore']->query($sparql_query); + // We only assign one in case of multiple ones + // Will have to check for edge cases? + foreach ($sparql_result as $triple) { + $app['data.resourcepath'] = $triple->s->getUri(); + } + // Abort the routes if we don't get a subject from the tripple. + if (NULL === $app['data.resourcepath']) { + $app->abort(404, sprintf('Failed getting resource Path for "%s"', $uuid)); + } }; /** * Convert returned Guzzle responses to Symfony responses. */ $app->view(function (ResponseInterface $psr7) { + return new Response($psr7->getBody(), $psr7->getStatusCode(), $psr7->getHeaders()); }); + /** * resource GET route. takes an UUID as first value to match, optional a child resource path * takes 'rx' and/or 'metadata' as optional query arguments * @see https://wiki.duraspace.org/display/FEDORA40/RESTful+HTTP+API#RESTfulHTTPAPI-GETRetrievethecontentoftheresource */ $app->get("/islandora/resource/{uuid}/{child}",function (\Silex\Application $app, Request $request, $uuid, $child) { - if (NULL === $app['data.resourcepath']) { - $app->abort(404, 'Failed getting resource Path for {$uuid}'); - } - $tx = $request->query->get('tx',""); - $metadata = $request->query->get('metadata',FALSE) ? '/fcr:metadata' : ""; + $tx = $request->query->get('tx', ""); + $metadata = $request->query->get('metadata', FALSE) ? '/fcr:metadata' : ""; $response = $app['fedora']->getResource($app->escape($app['data.resourcepath']) . '/' . $child . $metadata , $request->headers->all(), $tx); - if (NULL === $response ) - { - $app->abort(404, 'Failed getting resource from Fedora4'); - } + if (NULL === $response) { + $app->abort(404, 'Failed getting resource from Fedora4'); + } + return $response; }) ->value('child',"") @@ -89,50 +97,59 @@ * @see https://wiki.duraspace.org/display/FEDORA40/RESTful+HTTP+API#RESTfulHTTPAPI-BluePOSTCreatenewresourceswithinaLDPcontainer */ $app->post("/islandora/resource/{uuid}",function (\Silex\Application $app, Request $request, $uuid, $checksum) { - if (NULL === $app['data.resourcepath']) { - $app->abort(404, 'Failed getting resource Path for {$uuid}'); - } - $tx = $request->query->get('tx',""); - $checksum = $request->query->get('checksum',""); + $tx = $request->query->get('tx', ""); + $checksum = $request->query->get('checksum', ""); $response = $app['fedora']->createResource($app->escape($app['data.resourcepath']), $request->getContent(), $request->headers->all(), $tx, $checksum); - if (NULL === $response ) - { - $app->abort(404, 'Failed creating resource from Fedora4'); - } + if (NULL === $response) { + $app->abort(404, 'Failed creating resource in Fedora4'); + } + return $response; }) ->assert('uuid','([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})') ->before($getPathFromTriple); -$app->after(function (Request $request, Response $response, \Silex\Application $app) { -}); - /** * resource PUT route. takes an UUID for the resource to be update/created as first value to match, * optional a Child resource relative path - * takes 'rx' and/or 'checksum' as query arguments - * @see https://wiki.duraspace.org/display/FEDORA40/RESTful+HTTP+API#RESTfulHTTPAPI-BluePOSTCreatenewresourceswithinaLDPcontainer + * takes 'rx' and/or 'checksum' as optional query arguments + * @see https://wiki.duraspace.org/display/FEDORA40/RESTful+HTTP+API#RESTfulHTTPAPI-YellowPUTCreatearesourcewithaspecifiedpath,orreplacethetriplesassociatedwitharesourcewiththetriplesprovidedintherequestbody. */ $app->put("/islandora/resource/{uuid}/{child}",function (\Silex\Application $app, Request $request, $uuid, $child) { - if (NULL === $app['data.resourcepath']) { - $app->abort(404, 'Failed getting resource Path for {$uuid}'); - } - $tx = $request->query->get('tx',""); - $checksum = $request->query->get('checksum',""); - $response = $app['fedora']->saveResource($app->escape($app['data.resourcepath']) . '/' . $child, $request->getContent(), $request->headers->all(), $tx, $checksum); - if (NULL === $response ) - { - $app->abort(404, 'Failed putting resource into Fedora4'); - } + $tx = $request->query->get('tx', ""); + $checksum = $request->query->get('checksum', ""); + $response = $app['fedora']->saveResource($app->escape($app['data.resourcepath']).'/'.$child, $request->getContent(), $request->headers->all(), $tx, $checksum); + if (NULL === $response) { + $app->abort(404, 'Failed putting resource into Fedora4'); + } + return $response; }) ->value('child',"") ->assert('uuid','([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})') ->before($getPathFromTriple); +/** +* resource PATCH route. takes an UUID for the resource to be modified via SPARQL as first value to match, +* optional a Child resource relative path +* takes 'rx' as optional query argument +* @see https://wiki.duraspace.org/display/FEDORA40/RESTful+HTTP+API#RESTfulHTTPAPI-GreenPATCHModifythetriplesassociatedwitharesourcewithSPARQL-Update +*/ +$app->patch("/islandora/resource/{uuid}/{child}",function (\Silex\Application $app, Request $request, $uuid, $child) { + $tx = $request->query->get('tx', ""); + $response = $app['fedora']->modifyResource($app->escape($app['data.resourcepath']).'/'.$child, $request->getContent(), $request->headers->all(), $tx); + if (NULL === $response) { + $app->abort(404, 'Failed modifying resource in Fedora4'); + } + + return $response; +}) +->value('child',"") +->assert('uuid','([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})') +->before($getPathFromTriple); + $app->after(function (Request $request, Response $response, \Silex\Application $app) { + // Todo a closing controller, not sure what now but i had an idea. }); - - $app->run(); From 4b845721f8f3282754b6ec7b6615208e8062b671 Mon Sep 17 00:00:00 2001 From: Daniel Lamb Date: Fri, 18 Dec 2015 15:54:20 -0400 Subject: [PATCH 10/13] Using app->share in TransactionService. --- services/TransactionService/src/index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/TransactionService/src/index.php b/services/TransactionService/src/index.php index a4d8baf87..f5fa3019a 100644 --- a/services/TransactionService/src/index.php +++ b/services/TransactionService/src/index.php @@ -16,9 +16,9 @@ $app['debug'] = true; -$app['fedora'] = function () use ($app) { +$app['fedora'] = $app->share(function () { return FedoraApi::create('http://127.0.0.1:8080/fcrepo/rest'); -}; +}); /** * Convert returned Guzzle responses to Symfony responses. From 24513d7f1ea32447f5c11a602c8e560121f51b6c Mon Sep 17 00:00:00 2001 From: DiegoPino Date: Mon, 4 Jan 2016 17:41:36 -0300 Subject: [PATCH 11/13] Work In progress but better now * Added simplistic yaml config reader * Added middleware to handle empty $id in case of referencing root resource * Added error handler/catcher for unavailable Fedora and tripplestore services * Moved regex for uuid to config variable, not allows UUID V4 or empty * added Delete resource with ?force=true option in route to also remove tombstone in one step, can be used also on an existing tombstone Todo: * make a UUID/rdf generating service to generate intermediate resources in case of PUT and POST(if needed, still not convinced if really needed at this side) * check for mime types in case of updating existing resources, abort before hitting fedora if trying to "convert" and rdf->to binary or the other way resource. * Make messages more human friendly * Documentation --- .gitignore | 2 + services/ResourceService/composer.json | 2 +- services/ResourceService/composer.lock | 1150 ----------------- .../ResourceService/config/settings.dev.yml | 9 + services/ResourceService/config/settings.yml | 8 + services/ResourceService/src/index.php | 215 ++- 6 files changed, 175 insertions(+), 1211 deletions(-) delete mode 100644 services/ResourceService/composer.lock create mode 100644 services/ResourceService/config/settings.dev.yml create mode 100644 services/ResourceService/config/settings.yml diff --git a/.gitignore b/.gitignore index ed28125d5..826af1be1 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ tests/test_config.ini install/.vagrant install/downloads site/ + +services/ResourceService/composer.lock diff --git a/services/ResourceService/composer.json b/services/ResourceService/composer.json index 36653ec10..3fc9f5c7e 100644 --- a/services/ResourceService/composer.json +++ b/services/ResourceService/composer.json @@ -12,7 +12,7 @@ "silex/silex": "^1.3", "symfony/config": "^3.0", "twig/twig": "^1.23", - "symfony/psr-http-message-bridge": "^0.2.0" + "symfony/yaml": "^3.0" }, "autoload": { "psr-4": {"Islandora\\ResourceService\\": "src/"} diff --git a/services/ResourceService/composer.lock b/services/ResourceService/composer.lock deleted file mode 100644 index 00f04f8f5..000000000 --- a/services/ResourceService/composer.lock +++ /dev/null @@ -1,1150 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", - "This file is @generated automatically" - ], - "hash": "726c84778cf8771ea85150f2139b5c1c", - "content-hash": "5cd13cdb32f435a17777da8019399d72", - "packages": [ - { - "name": "easyrdf/easyrdf", - "version": "0.9.0", - "source": { - "type": "git", - "url": "https://github.com/njh/easyrdf.git", - "reference": "bb9fd99768d23af0c5b7b55cec5baddc201272b8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/njh/easyrdf/zipball/bb9fd99768d23af0c5b7b55cec5baddc201272b8", - "reference": "bb9fd99768d23af0c5b7b55cec5baddc201272b8", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "ext-pcre": "*", - "php": ">=5.2.8" - }, - "require-dev": { - "phpunit/phpunit": "~3.5", - "sami/sami": "~1.4", - "squizlabs/php_codesniffer": "~1.4.3" - }, - "suggest": { - "ml/json-ld": "~1.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "EasyRdf_": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nicholas Humfrey", - "email": "njh@aelius.com", - "homepage": "http://www.aelius.com/njh/", - "role": "Developer" - }, - { - "name": "Alexey Zakhlestin", - "email": "indeyets@gmail.com", - "role": "Developer" - } - ], - "description": "EasyRdf is a PHP library designed to make it easy to consume and produce RDF.", - "homepage": "http://www.easyrdf.org/", - "keywords": [ - "Linked Data", - "RDF", - "Semantic Web", - "Turtle", - "rdfa", - "sparql" - ], - "time": "2014-11-07 18:02:16" - }, - { - "name": "guzzlehttp/guzzle", - "version": "6.1.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "66fd14b4d0b8f2389eaf37c5458608c7cb793a81" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/66fd14b4d0b8f2389eaf37c5458608c7cb793a81", - "reference": "66fd14b4d0b8f2389eaf37c5458608c7cb793a81", - "shasum": "" - }, - "require": { - "guzzlehttp/promises": "~1.0", - "guzzlehttp/psr7": "~1.1", - "php": ">=5.5.0" - }, - "require-dev": { - "ext-curl": "*", - "phpunit/phpunit": "~4.0", - "psr/log": "~1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.1-dev" - } - }, - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "GuzzleHttp\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle is a PHP HTTP client library", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "rest", - "web service" - ], - "time": "2015-09-08 17:36:26" - }, - { - "name": "guzzlehttp/promises", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/b1e1c0d55f8083c71eda2c28c12a228d708294ea", - "reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea", - "shasum": "" - }, - "require": { - "php": ">=5.5.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Promise\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle promises library", - "keywords": [ - "promise" - ], - "time": "2015-10-15 22:28:00" - }, - { - "name": "guzzlehttp/psr7", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "4d0bdbe1206df7440219ce14c972aa57cc5e4982" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/4d0bdbe1206df7440219ce14c972aa57cc5e4982", - "reference": "4d0bdbe1206df7440219ce14c972aa57cc5e4982", - "shasum": "" - }, - "require": { - "php": ">=5.4.0", - "psr/http-message": "~1.0" - }, - "provide": { - "psr/http-message-implementation": "1.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "PSR-7 message implementation", - "keywords": [ - "http", - "message", - "stream", - "uri" - ], - "time": "2015-11-03 01:34:55" - }, - { - "name": "islandora/chullo", - "version": "dev-api", - "source": { - "type": "git", - "url": "/Users/dpino/Desktop/Development/ISLANDORAWORK/CLAW_MICRO/chullo", - "reference": "f8a03d7cd4bff0712c4e5e925d70108d03d17829" - }, - "require": { - "easyrdf/easyrdf": "0.9.0", - "guzzlehttp/guzzle": "6.1.0", - "ml/json-ld": "1.0.3", - "php": ">=5.5.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8" - }, - "type": "library", - "autoload": { - "psr-4": { - "Islandora\\Chullo\\": "src/" - } - }, - "license": [ - "GPLv3" - ], - "authors": [ - { - "name": "Islandora Foundation", - "email": "community@islandora.ca", - "role": "Owner" - }, - { - "name": "Daniel Lamb", - "email": "daniel@discoverygarden.ca", - "role": "Maintainer" - }, - { - "name": "Nick Ruest", - "email": "ruestn@gmail.com", - "role": "Maintainer" - } - ], - "description": "A PHP client for interacting with a Fedora 4 server.", - "homepage": "https://github.com/islandora-claw/chullo", - "support": { - "issues": "https://github.com/islandora-claw/chullo/issues", - "irc": "irc://irc.freenode.net/islandora" - }, - "time": "2015-12-16 17:32:51" - }, - { - "name": "ml/iri", - "version": "1.1.4", - "target-dir": "ML/IRI", - "source": { - "type": "git", - "url": "https://github.com/lanthaler/IRI.git", - "reference": "cbd44fa913e00ea624241b38cefaa99da8d71341" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/lanthaler/IRI/zipball/cbd44fa913e00ea624241b38cefaa99da8d71341", - "reference": "cbd44fa913e00ea624241b38cefaa99da8d71341", - "shasum": "" - }, - "require": { - "lib-pcre": ">=4.0", - "php": ">=5.3.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "ML\\IRI": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Markus Lanthaler", - "email": "mail@markus-lanthaler.com", - "homepage": "http://www.markus-lanthaler.com", - "role": "Developer" - } - ], - "description": "IRI handling for PHP", - "homepage": "http://www.markus-lanthaler.com", - "keywords": [ - "URN", - "iri", - "uri", - "url" - ], - "time": "2014-01-21 13:43:39" - }, - { - "name": "ml/json-ld", - "version": "1.0.3", - "target-dir": "ML/JsonLD", - "source": { - "type": "git", - "url": "https://github.com/lanthaler/JsonLD.git", - "reference": "10a03f7dec0f4a7db6b2e6e6230cdfb7cce562a2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/lanthaler/JsonLD/zipball/10a03f7dec0f4a7db6b2e6e6230cdfb7cce562a2", - "reference": "10a03f7dec0f4a7db6b2e6e6230cdfb7cce562a2", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ml/iri": ">=1.1.1", - "php": ">=5.3.0" - }, - "require-dev": { - "json-ld/tests": "@dev" - }, - "type": "library", - "autoload": { - "psr-0": { - "ML\\JsonLD": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Markus Lanthaler", - "email": "mail@markus-lanthaler.com", - "homepage": "http://www.markus-lanthaler.com", - "role": "Developer" - } - ], - "description": "JSON-LD Processor for PHP", - "homepage": "http://www.markus-lanthaler.com", - "keywords": [ - "JSON-LD", - "jsonld" - ], - "time": "2014-09-15 10:41:19" - }, - { - "name": "pimple/pimple", - "version": "v1.1.1", - "source": { - "type": "git", - "url": "https://github.com/silexphp/Pimple.git", - "reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/silexphp/Pimple/zipball/2019c145fe393923f3441b23f29bbdfaa5c58c4d", - "reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "autoload": { - "psr-0": { - "Pimple": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "Pimple is a simple Dependency Injection Container for PHP 5.3", - "homepage": "http://pimple.sensiolabs.org", - "keywords": [ - "container", - "dependency injection" - ], - "time": "2013-11-22 08:30:29" - }, - { - "name": "psr/http-message", - "version": "1.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", - "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "time": "2015-05-04 20:22:00" - }, - { - "name": "psr/log", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", - "shasum": "" - }, - "type": "library", - "autoload": { - "psr-0": { - "Psr\\Log\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "time": "2012-12-21 11:40:51" - }, - { - "name": "silex/silex", - "version": "v1.3.4", - "source": { - "type": "git", - "url": "https://github.com/silexphp/Silex.git", - "reference": "d6de62716fcda76084f3015165125f30b1563517" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/silexphp/Silex/zipball/d6de62716fcda76084f3015165125f30b1563517", - "reference": "d6de62716fcda76084f3015165125f30b1563517", - "shasum": "" - }, - "require": { - "php": ">=5.3.9", - "pimple/pimple": "~1.0", - "symfony/event-dispatcher": "~2.3|3.0.*", - "symfony/http-foundation": "~2.3|3.0.*", - "symfony/http-kernel": "~2.3|3.0.*", - "symfony/routing": "~2.3|3.0.*" - }, - "require-dev": { - "doctrine/dbal": "~2.2", - "monolog/monolog": "^1.4.1", - "swiftmailer/swiftmailer": "~5", - "symfony/browser-kit": "~2.3|3.0.*", - "symfony/config": "~2.3|3.0.*", - "symfony/css-selector": "~2.3|3.0.*", - "symfony/debug": "~2.3|3.0.*", - "symfony/dom-crawler": "~2.3|3.0.*", - "symfony/finder": "~2.3|3.0.*", - "symfony/form": "~2.3|3.0.*", - "symfony/locale": "~2.3|3.0.*", - "symfony/monolog-bridge": "~2.3|3.0.*", - "symfony/options-resolver": "~2.3|3.0.*", - "symfony/phpunit-bridge": "~2.7", - "symfony/process": "~2.3|3.0.*", - "symfony/security": "~2.3|3.0.*", - "symfony/serializer": "~2.3|3.0.*", - "symfony/translation": "~2.3|3.0.*", - "symfony/twig-bridge": "~2.3|3.0.*", - "symfony/validator": "~2.3|3.0.*", - "twig/twig": "~1.8|~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Silex\\": "src/Silex" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Igor Wiedler", - "email": "igor@wiedler.ch" - } - ], - "description": "The PHP micro-framework based on the Symfony Components", - "homepage": "http://silex.sensiolabs.org", - "keywords": [ - "microframework" - ], - "time": "2015-09-15 06:53:42" - }, - { - "name": "symfony/config", - "version": "v3.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/config.git", - "reference": "40bae8658dbbb500ebc19aa9fde22dc4295fc290" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/40bae8658dbbb500ebc19aa9fde22dc4295fc290", - "reference": "40bae8658dbbb500ebc19aa9fde22dc4295fc290", - "shasum": "" - }, - "require": { - "php": ">=5.5.9", - "symfony/filesystem": "~2.8|~3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Config\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Config Component", - "homepage": "https://symfony.com", - "time": "2015-11-02 20:34:04" - }, - { - "name": "symfony/debug", - "version": "v3.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/debug.git", - "reference": "0623b00095f0833412ee6f92f421e9adf4c7e113" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/0623b00095f0833412ee6f92f421e9adf4c7e113", - "reference": "0623b00095f0833412ee6f92f421e9adf4c7e113", - "shasum": "" - }, - "require": { - "php": ">=5.5.9", - "psr/log": "~1.0" - }, - "conflict": { - "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" - }, - "require-dev": { - "symfony/class-loader": "~2.8|~3.0", - "symfony/http-kernel": "~2.8|~3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Debug\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Debug Component", - "homepage": "https://symfony.com", - "time": "2015-11-27 05:46:53" - }, - { - "name": "symfony/event-dispatcher", - "version": "v3.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "d36355e026905fa5229e1ed7b4e9eda2e67adfcf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d36355e026905fa5229e1ed7b4e9eda2e67adfcf", - "reference": "d36355e026905fa5229e1ed7b4e9eda2e67adfcf", - "shasum": "" - }, - "require": { - "php": ">=5.5.9" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "~2.8|~3.0", - "symfony/dependency-injection": "~2.8|~3.0", - "symfony/expression-language": "~2.8|~3.0", - "symfony/stopwatch": "~2.8|~3.0" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony EventDispatcher Component", - "homepage": "https://symfony.com", - "time": "2015-10-30 23:35:59" - }, - { - "name": "symfony/filesystem", - "version": "v3.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "692d98d813e4ef314b9c22775c86ddbeb0f44884" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/692d98d813e4ef314b9c22775c86ddbeb0f44884", - "reference": "692d98d813e4ef314b9c22775c86ddbeb0f44884", - "shasum": "" - }, - "require": { - "php": ">=5.5.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Filesystem\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Filesystem Component", - "homepage": "https://symfony.com", - "time": "2015-11-23 10:41:47" - }, - { - "name": "symfony/http-foundation", - "version": "v3.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-foundation.git", - "reference": "1563f784900958afdb584ca82a072c578ed8a929" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/1563f784900958afdb584ca82a072c578ed8a929", - "reference": "1563f784900958afdb584ca82a072c578ed8a929", - "shasum": "" - }, - "require": { - "php": ">=5.5.9" - }, - "require-dev": { - "symfony/expression-language": "~2.8|~3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\HttpFoundation\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony HttpFoundation Component", - "homepage": "https://symfony.com", - "time": "2015-11-27 14:30:17" - }, - { - "name": "symfony/http-kernel", - "version": "v3.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-kernel.git", - "reference": "2f7071c25cae37b79be6d9ea1c43c1035d8c6b06" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/2f7071c25cae37b79be6d9ea1c43c1035d8c6b06", - "reference": "2f7071c25cae37b79be6d9ea1c43c1035d8c6b06", - "shasum": "" - }, - "require": { - "php": ">=5.5.9", - "psr/log": "~1.0", - "symfony/debug": "~2.8|~3.0", - "symfony/event-dispatcher": "~2.8|~3.0", - "symfony/http-foundation": "~2.8|~3.0" - }, - "conflict": { - "symfony/config": "<2.8" - }, - "require-dev": { - "symfony/browser-kit": "~2.8|~3.0", - "symfony/class-loader": "~2.8|~3.0", - "symfony/config": "~2.8|~3.0", - "symfony/console": "~2.8|~3.0", - "symfony/css-selector": "~2.8|~3.0", - "symfony/dependency-injection": "~2.8|~3.0", - "symfony/dom-crawler": "~2.8|~3.0", - "symfony/expression-language": "~2.8|~3.0", - "symfony/finder": "~2.8|~3.0", - "symfony/process": "~2.8|~3.0", - "symfony/routing": "~2.8|~3.0", - "symfony/stopwatch": "~2.8|~3.0", - "symfony/templating": "~2.8|~3.0", - "symfony/translation": "~2.8|~3.0", - "symfony/var-dumper": "~2.8|~3.0" - }, - "suggest": { - "symfony/browser-kit": "", - "symfony/class-loader": "", - "symfony/config": "", - "symfony/console": "", - "symfony/dependency-injection": "", - "symfony/finder": "", - "symfony/var-dumper": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\HttpKernel\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony HttpKernel Component", - "homepage": "https://symfony.com", - "time": "2015-11-30 20:59:24" - }, - { - "name": "symfony/psr-http-message-bridge", - "version": "v0.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/psr-http-message-bridge.git", - "reference": "dc7e308e1dc2898a46776e2221a643cb08315453" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/dc7e308e1dc2898a46776e2221a643cb08315453", - "reference": "dc7e308e1dc2898a46776e2221a643cb08315453", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "psr/http-message": "~1.0", - "symfony/http-foundation": "~2.3|~3.0" - }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7|~3.0" - }, - "suggest": { - "zendframework/zend-diactoros": "To use the Zend Diactoros factory" - }, - "type": "symfony-bridge", - "autoload": { - "psr-4": { - "Symfony\\Bridge\\PsrHttpMessage\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "PSR HTTP message bridge", - "homepage": "http://symfony.com", - "keywords": [ - "http", - "http-message", - "psr-7" - ], - "time": "2015-05-29 17:57:12" - }, - { - "name": "symfony/routing", - "version": "v3.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/routing.git", - "reference": "252014dfa4685e80f9216ae4b7d78b1a50dd55c2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/252014dfa4685e80f9216ae4b7d78b1a50dd55c2", - "reference": "252014dfa4685e80f9216ae4b7d78b1a50dd55c2", - "shasum": "" - }, - "require": { - "php": ">=5.5.9" - }, - "conflict": { - "symfony/config": "<2.8" - }, - "require-dev": { - "doctrine/annotations": "~1.0", - "doctrine/common": "~2.2", - "psr/log": "~1.0", - "symfony/config": "~2.8|~3.0", - "symfony/expression-language": "~2.8|~3.0", - "symfony/http-foundation": "~2.8|~3.0", - "symfony/yaml": "~2.8|~3.0" - }, - "suggest": { - "doctrine/annotations": "For using the annotation loader", - "symfony/config": "For using the all-in-one router or any loader", - "symfony/dependency-injection": "For loading routes from a service", - "symfony/expression-language": "For using expression matching", - "symfony/yaml": "For using the YAML loader" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Routing\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Routing Component", - "homepage": "https://symfony.com", - "keywords": [ - "router", - "routing", - "uri", - "url" - ], - "time": "2015-11-26 07:02:09" - }, - { - "name": "twig/twig", - "version": "v1.23.1", - "source": { - "type": "git", - "url": "https://github.com/twigphp/Twig.git", - "reference": "d9b6333ae8dd2c8e3fd256e127548def0bc614c6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/d9b6333ae8dd2c8e3fd256e127548def0bc614c6", - "reference": "d9b6333ae8dd2c8e3fd256e127548def0bc614c6", - "shasum": "" - }, - "require": { - "php": ">=5.2.7" - }, - "require-dev": { - "symfony/debug": "~2.7", - "symfony/phpunit-bridge": "~2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.23-dev" - } - }, - "autoload": { - "psr-0": { - "Twig_": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "role": "Project Founder" - }, - { - "name": "Twig Team", - "homepage": "http://twig.sensiolabs.org/contributors", - "role": "Contributors" - } - ], - "description": "Twig, the flexible, fast, and secure template language for PHP", - "homepage": "http://twig.sensiolabs.org", - "keywords": [ - "templating" - ], - "time": "2015-11-05 12:49:06" - } - ], - "packages-dev": [], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": { - "islandora/chullo": 20 - }, - "prefer-stable": false, - "prefer-lowest": false, - "platform": [], - "platform-dev": [] -} diff --git a/services/ResourceService/config/settings.dev.yml b/services/ResourceService/config/settings.dev.yml new file mode 100644 index 000000000..4c88cff65 --- /dev/null +++ b/services/ResourceService/config/settings.dev.yml @@ -0,0 +1,9 @@ +# Islandora Dev Settings to be used with $app['debug'] == TRUE +islandora: + fedoraProtocol: http + fedoraHost: "localhost:8080" + fedoraPath: /rest + tripleProtocol: http + tripleHost: "localhost:9999" + triplePath: /bigdata/sparql + resourceIdRegex: "(?:[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})?" \ No newline at end of file diff --git a/services/ResourceService/config/settings.yml b/services/ResourceService/config/settings.yml new file mode 100644 index 000000000..00a4370f8 --- /dev/null +++ b/services/ResourceService/config/settings.yml @@ -0,0 +1,8 @@ +islandora: + fedoraProtocol: http + fedoraHost: "localhost:8080" + fedoraPath: /fcrepo/rest + tripleProtocol: http + tripleHost: "localhost:8080" + triplePath: /bigdata/sparql + resourceIdRegex: "(?:[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})?" \ No newline at end of file diff --git a/services/ResourceService/src/index.php b/services/ResourceService/src/index.php index 27050c78b..af0973dcf 100644 --- a/services/ResourceService/src/index.php +++ b/services/ResourceService/src/index.php @@ -5,19 +5,18 @@ require_once __DIR__.'/../vendor/autoload.php'; use Silex\Application; -use Islandora\Chullo\Chullo; +use Islandora\Chullo\FedoraApi; use Islandora\Chullo\TriplestoreClient; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\HttpKernelInterface; use Psr\Http\Message\ResponseInterface; use Silex\Provider\TwigServiceProvider; -use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory; - +use Symfony\Component\Yaml\Yaml; date_default_timezone_set('UTC'); -$app = new \Silex\Application(); +$app = new Application(); $app['debug'] = true; @@ -25,131 +24,227 @@ 'twig.path' => __DIR__.'/../templates', )); -$app['twig'] = $app->share($app->extend('twig', function($twig, $app) { +$app['twig'] = $app->share($app->extend('twig', function($twig, $app) { return $twig; })); -$app['fedora'] = $app->share(function() { - - return Chullo::create('http://localhost:8080/rest'); +$app['api'] = $app->share(function() use ($app) { + return FedoraApi::create($app['config']['islandora']['fedoraProtocol'].'://'.$app['config']['islandora']['fedoraHost'].$app['config']['islandora']['fedoraPath']); }); -$app['triplestore'] = $app->share(function() { - - return TriplestoreClient::create('http://localhost:9999/bigdata/sparql'); +$app['triplestore'] = $app->share(function() use ($app) { + return TriplestoreClient::create($app['config']['islandora']['tripleProtocol'].'://'.$app['config']['islandora']['tripleHost'].$app['config']['islandora']['triplePath']); }); -$app['data.resourcepath'] = NULL; +/** + * Ultra simplistic YAML settings loader. + */ +$app['config'] = $app->share(function() use ($app){ + if ($app['debug']) { + $configFile = __DIR__.'/../config/settings.dev.yml'; + } + else { + $configFile = __DIR__.'/../config/settings.yml'; + } + $settings = Yaml::parse(file_get_contents($configFile)); + return $settings; +}); -$getPathFromTriple = function (Request $request,\Silex\Application $app) { +/** + * before middleware to handle browser requests. + */ +$htmlHeaderToTurtle = function(Request $request) { // In case the request was made by a browser, avoid // returning the whole Fedora4 API Rest interface page. if (0 === strpos($request->headers->get('Accept'),'text/html')) { $request->headers->set('Accept', 'text/turtle', TRUE); } - $sparql_query = $app['twig']->render('getResourceByUUIDfromTS.sparql', array( - 'uuid' => $request->attributes->get('uuid'), - )); - - $sparql_result = $app['triplestore']->query($sparql_query); - // We only assign one in case of multiple ones - // Will have to check for edge cases? - foreach ($sparql_result as $triple) { - $app['data.resourcepath'] = $triple->s->getUri(); - } - // Abort the routes if we don't get a subject from the tripple. - if (NULL === $app['data.resourcepath']) { - $app->abort(404, sprintf('Failed getting resource Path for "%s"', $uuid)); +}; + + +/** + * before middleware to normalize host header to same as fedora's running + * instance. + */ +$hostHeaderNormalize = function(Request $request) use ($app) { + // Normalize Host header to Repo's real location + $request->headers->set('Host', $app['config']['islandora']['fedoraHost'], TRUE); +}; + +/** + * Converts request $id (uuid) into a fedora4 resourcePath + */ +$idToUri = function ($id) use ($app) { + // Run only if $id given /can also be refering root resource, + // we accept only UUID V4 or empty + if (NULL != $id) { + $sparql_query = $app['twig']->render('getResourceByUUIDfromTS.sparql', array( + 'uuid' => $id, + )); + try { + $sparql_result = $app['triplestore']->query($sparql_query); + } + catch (\Exception $e) { + $app->abort(503, 'Chullo says "Triple Store Not available"'); + } + // We only assign one in case of multiple ones + // Will have to check for edge cases? + foreach ($sparql_result as $triple) { + return $triple->s->getUri(); + } + // Abort the routes if we don't get a subject from the tripple. + $app->abort(404, sprintf('Failed getting resource Path for "%s" from triple store', $id)); + } + else { + // If $id is empty then assume we are dealing with fedora base rest endpoint + return $app['config']['islandora']['fedoraProtocol'].'://'.$app['config']['islandora']['fedoraHost'].$app['config']['islandora']['fedoraPath']; } + }; /** * Convert returned Guzzle responses to Symfony responses. */ $app->view(function (ResponseInterface $psr7) { - return new Response($psr7->getBody(), $psr7->getStatusCode(), $psr7->getHeaders()); }); /** - * resource GET route. takes an UUID as first value to match, optional a child resource path + * Resource GET route. takes $id (valid UUID or empty) as first value to match, optional a child resource path * takes 'rx' and/or 'metadata' as optional query arguments * @see https://wiki.duraspace.org/display/FEDORA40/RESTful+HTTP+API#RESTfulHTTPAPI-GETRetrievethecontentoftheresource */ -$app->get("/islandora/resource/{uuid}/{child}",function (\Silex\Application $app, Request $request, $uuid, $child) { +$app->get("/islandora/resource/{id}/{child}",function (Application $app, Request $request, $id, $child) { $tx = $request->query->get('tx', ""); $metadata = $request->query->get('metadata', FALSE) ? '/fcr:metadata' : ""; - $response = $app['fedora']->getResource($app->escape($app['data.resourcepath']) . '/' . $child . $metadata , $request->headers->all(), $tx); - if (NULL === $response) { - $app->abort(404, 'Failed getting resource from Fedora4'); + try { + $response = $app['api']->getResource($app->escape($id).'/'.$child.$metadata, $request->headers->all(), $tx); + } + catch (\Exception $e) { + $app->abort(503, 'Chullo says "Fedora4 Repository Not available"'); } - return $response; }) ->value('child',"") -->assert('uuid','([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})') -->before($getPathFromTriple); +->value('id',"") +->convert('id', $idToUri) +->assert('id',$app['config']['islandora']['resourceIdRegex']) +->before($htmlHeaderToTurtle) +->before($hostHeaderNormalize); /** - * resource POST route. takes an UUID for the parent resource as first value to match + * Resource POST route. takes $id (valid UUID or empty) for the parent resource as first value to match * takes 'rx' and/or 'checksum' as optional query arguments * @see https://wiki.duraspace.org/display/FEDORA40/RESTful+HTTP+API#RESTfulHTTPAPI-BluePOSTCreatenewresourceswithinaLDPcontainer */ -$app->post("/islandora/resource/{uuid}",function (\Silex\Application $app, Request $request, $uuid, $checksum) { +$app->post("/islandora/resource/{id}",function (Application $app, Request $request, $id, $checksum) { $tx = $request->query->get('tx', ""); $checksum = $request->query->get('checksum', ""); - $response = $app['fedora']->createResource($app->escape($app['data.resourcepath']), $request->getContent(), $request->headers->all(), $tx, $checksum); - if (NULL === $response) { - $app->abort(404, 'Failed creating resource in Fedora4'); + try { + $response = $app['api']->createResource($app->escape($id), $request->getContent(), $request->headers->all(), $tx, $checksum); + } + catch (\Exception $e) { + $app->abort(503, '"Chullo says Fedora4 Repository is Not available"'); } - return $response; }) -->assert('uuid','([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})') -->before($getPathFromTriple); +->value('id',"") +->assert('id',$app['config']['islandora']['resourceIdRegex']) +->before($htmlHeaderToTurtle) +->before($hostHeaderNormalize); /** - * resource PUT route. takes an UUID for the resource to be update/created as first value to match, + * Resource PUT route. takes $id (valid UUID or empty) for the resource to be update/created as first value to match, * optional a Child resource relative path * takes 'rx' and/or 'checksum' as optional query arguments * @see https://wiki.duraspace.org/display/FEDORA40/RESTful+HTTP+API#RESTfulHTTPAPI-YellowPUTCreatearesourcewithaspecifiedpath,orreplacethetriplesassociatedwitharesourcewiththetriplesprovidedintherequestbody. */ -$app->put("/islandora/resource/{uuid}/{child}",function (\Silex\Application $app, Request $request, $uuid, $child) { +$app->put("/islandora/resource/{id}/{child}",function (Application $app, Request $request, $id, $child) { $tx = $request->query->get('tx', ""); $checksum = $request->query->get('checksum', ""); - $response = $app['fedora']->saveResource($app->escape($app['data.resourcepath']).'/'.$child, $request->getContent(), $request->headers->all(), $tx, $checksum); - if (NULL === $response) { - $app->abort(404, 'Failed putting resource into Fedora4'); + try { + $response = $app['api']->saveResource($app->escape($id).'/'.$child, $request->getContent(), $request->headers->all(), $tx, $checksum); + } + catch (\Exception $e) { + $app->abort(503, '"Chullo says Fedora4 Repository is Not available"'); } - return $response; }) ->value('child',"") -->assert('uuid','([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})') -->before($getPathFromTriple); +->assert('id',$app['config']['islandora']['resourceIdRegex']) +->before($htmlHeaderToTurtle) +->before($hostHeaderNormalize); /** -* resource PATCH route. takes an UUID for the resource to be modified via SPARQL as first value to match, +* Resource PATCH route. takes $id (valid UUID or empty) for the resource to be modified via SPARQL as first value to match, * optional a Child resource relative path * takes 'rx' as optional query argument * @see https://wiki.duraspace.org/display/FEDORA40/RESTful+HTTP+API#RESTfulHTTPAPI-GreenPATCHModifythetriplesassociatedwitharesourcewithSPARQL-Update */ -$app->patch("/islandora/resource/{uuid}/{child}",function (\Silex\Application $app, Request $request, $uuid, $child) { +$app->patch("/islandora/resource/{id}/{child}",function (Application $app, Request $request, $id, $child) { $tx = $request->query->get('tx', ""); - $response = $app['fedora']->modifyResource($app->escape($app['data.resourcepath']).'/'.$child, $request->getContent(), $request->headers->all(), $tx); - if (NULL === $response) { - $app->abort(404, 'Failed modifying resource in Fedora4'); + try { + $response = $app['api']->modifyResource($app->escape($id).'/'.$child, $request->getContent(), $request->headers->all(), $tx); + } + catch (\Exception $e) { + $app->abort(503, '"Chullo says Fedora4 Repository is Not available"'); } - return $response; }) ->value('child',"") -->assert('uuid','([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})') -->before($getPathFromTriple); +->assert('id',$app['config']['islandora']['resourceIdRegex']) +->before($htmlHeaderToTurtle) +->before($hostHeaderNormalize); -$app->after(function (Request $request, Response $response, \Silex\Application $app) { +/** +* Resource DELETE route. takes $id (valid UUID or empty) for the resource to be modified via SPARQL as first value to match, +* optional a Child resource relative path +* takes 'rx' as optional query argument, also 'force' to remove the tombstone in one step +* @see https://wiki.duraspace.org/display/FEDORA40/RESTful+HTTP+API#RESTfulHTTPAPI-RedDELETEDeletearesource +*/ +$app->delete("/islandora/resource/{id}/{child}",function (Application $app, Request $request, $id, $child) { + $tx = $request->query->get('tx', ""); + $force = $request->query->get('force', FALSE); + try { + $response = $app['api']->deleteResource($app->escape($id).'/'.$child, $tx); + //remove tombstone also if 'force' == true and previous response is 204 + if ((204 == $response->getStatusCode() || 410 == $response->getStatusCode()) && $force) { + $response= $app['api']->deleteResource($app->escape($id).'/'.$child.'/fcr:tombstone', $tx); + } + } + catch (\Exception $e) { + $app->abort(503, '"Chullo says Fedora4 Repository is Not available"'); + } + return $response; +}) +->value('child',"") +->assert('id',$app['config']['islandora']['resourceIdRegex']) +->before($htmlHeaderToTurtle) +->before($hostHeaderNormalize); + +$app->after(function (Request $request, Response $response, Application $app) { // Todo a closing controller, not sure what now but i had an idea. }); +$app->error(function (\Symfony\Component\HttpKernel\Exception\HttpException $e, $code) use ($app){ + if ($app['debug']) { + return; + } + return new response(sprintf('Islandora Resource Service exception: %s / HTTP %d response', $e->getMessage(), $code), $code); +}); +$app->error(function (\Symfony\Component\HttpKernel\Exception\NotFoundHttpException $e, $code) use ($app){ + if ($app['debug']) { + return; + } + //Not sure what the best "verbose" message is + return new response(sprintf('Islandora Resource Service exception: %s / HTTP %d response', $e->getMessage(), $code), $code); +}); +$app->error(function (\Exception $e, $code) use ($app){ + if ($app['debug']) { + return; + } + return new response(sprintf('Islandora Resource Service uncatched exception: %s %d response', $e->getMessage(), $code), $code); +}); + $app->run(); From 0654a2bb7b71302e3767080f2bb62dd6ec599c83 Mon Sep 17 00:00:00 2001 From: DiegoPino Date: Wed, 13 Jan 2016 16:44:17 -0300 Subject: [PATCH 12/13] legacy var removed $checksum is optional, passed as get variable to the route ?checksum="urn:sha:somekey" --- services/ResourceService/src/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/ResourceService/src/index.php b/services/ResourceService/src/index.php index af0973dcf..6adc08d3e 100644 --- a/services/ResourceService/src/index.php +++ b/services/ResourceService/src/index.php @@ -138,7 +138,7 @@ * takes 'rx' and/or 'checksum' as optional query arguments * @see https://wiki.duraspace.org/display/FEDORA40/RESTful+HTTP+API#RESTfulHTTPAPI-BluePOSTCreatenewresourceswithinaLDPcontainer */ -$app->post("/islandora/resource/{id}",function (Application $app, Request $request, $id, $checksum) { +$app->post("/islandora/resource/{id}",function (Application $app, Request $request, $id) { $tx = $request->query->get('tx', ""); $checksum = $request->query->get('checksum', ""); try { From 2428860d7a0a099f438ada5afc27874c4114b965 Mon Sep 17 00:00:00 2001 From: DiegoPino Date: Wed, 13 Jan 2016 19:20:53 -0300 Subject: [PATCH 13/13] Unified middleware under global controllers Moved all common middleware to global controllers def. Cleaner code and easier to maintain. --- services/ResourceService/src/index.php | 40 ++++++++++++-------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/services/ResourceService/src/index.php b/services/ResourceService/src/index.php index 6adc08d3e..ee1128af2 100644 --- a/services/ResourceService/src/index.php +++ b/services/ResourceService/src/index.php @@ -100,9 +100,18 @@ // If $id is empty then assume we are dealing with fedora base rest endpoint return $app['config']['islandora']['fedoraProtocol'].'://'.$app['config']['islandora']['fedoraHost'].$app['config']['islandora']['fedoraPath']; } - }; +/** + * Apply middleware to all controllers +*/ +$app['controllers'] + ->convert('id', $idToUri) + ->assert('id',$app['config']['islandora']['resourceIdRegex']) + ->before($htmlHeaderToTurtle) + ->before($hostHeaderNormalize) +; + /** * Convert returned Guzzle responses to Symfony responses. */ @@ -126,12 +135,8 @@ } return $response; }) -->value('child',"") ->value('id',"") -->convert('id', $idToUri) -->assert('id',$app['config']['islandora']['resourceIdRegex']) -->before($htmlHeaderToTurtle) -->before($hostHeaderNormalize); +->value('child',""); /** * Resource POST route. takes $id (valid UUID or empty) for the parent resource as first value to match @@ -149,10 +154,7 @@ } return $response; }) -->value('id',"") -->assert('id',$app['config']['islandora']['resourceIdRegex']) -->before($htmlHeaderToTurtle) -->before($hostHeaderNormalize); +->value('id',""); /** * Resource PUT route. takes $id (valid UUID or empty) for the resource to be update/created as first value to match, @@ -171,10 +173,8 @@ } return $response; }) -->value('child',"") -->assert('id',$app['config']['islandora']['resourceIdRegex']) -->before($htmlHeaderToTurtle) -->before($hostHeaderNormalize); +->value('id',"") +->value('child',""); /** * Resource PATCH route. takes $id (valid UUID or empty) for the resource to be modified via SPARQL as first value to match, @@ -192,10 +192,8 @@ } return $response; }) -->value('child',"") -->assert('id',$app['config']['islandora']['resourceIdRegex']) -->before($htmlHeaderToTurtle) -->before($hostHeaderNormalize); +->value('id',"") +->value('child',""); /** * Resource DELETE route. takes $id (valid UUID or empty) for the resource to be modified via SPARQL as first value to match, @@ -218,10 +216,8 @@ } return $response; }) -->value('child',"") -->assert('id',$app['config']['islandora']['resourceIdRegex']) -->before($htmlHeaderToTurtle) -->before($hostHeaderNormalize); +->value('id',"") +->value('child',""); $app->after(function (Request $request, Response $response, Application $app) { // Todo a closing controller, not sure what now but i had an idea.