From 564c2e0bcebc71ad59f70d043d9e885ae719a926 Mon Sep 17 00:00:00 2001 From: DiegoPino Date: Wed, 20 Jan 2016 10:58:37 -0300 Subject: [PATCH 1/7] Alt Islandora ResourceService using providers Changed the one-file logic to full ServiceProvider and ControllerProvider. Allowed some external service injection/swapping possibilities for users, had to move the global middleware to specific middleware for each route to allow other silex apps to use and avoid all the transforms we do here --- .gitignore | 2 + services/ResourceServiceProvider/.gitignore | 1 + .../ResourceServiceProvider/composer.json | 26 +++ .../config/settings.dev.yml | 9 + .../config/settings.yml | 8 + .../src/Controller/ResourceController.php | 84 +++++++++ .../src/Provider/ResourceServiceProvider.php | 167 ++++++++++++++++++ .../ResourceServiceProvider/src/index.php | 63 +++++++ .../templates/getResourceByUUIDfromTS.sparql | 5 + 9 files changed, 365 insertions(+) create mode 100644 services/ResourceServiceProvider/.gitignore create mode 100644 services/ResourceServiceProvider/composer.json create mode 100644 services/ResourceServiceProvider/config/settings.dev.yml create mode 100644 services/ResourceServiceProvider/config/settings.yml create mode 100644 services/ResourceServiceProvider/src/Controller/ResourceController.php create mode 100644 services/ResourceServiceProvider/src/Provider/ResourceServiceProvider.php create mode 100644 services/ResourceServiceProvider/src/index.php create mode 100644 services/ResourceServiceProvider/templates/getResourceByUUIDfromTS.sparql diff --git a/.gitignore b/.gitignore index 826af1be1..5f92d46db 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ install/downloads site/ services/ResourceService/composer.lock + +services/ResourceServiceProvider/composer.lock diff --git a/services/ResourceServiceProvider/.gitignore b/services/ResourceServiceProvider/.gitignore new file mode 100644 index 000000000..48b8bf907 --- /dev/null +++ b/services/ResourceServiceProvider/.gitignore @@ -0,0 +1 @@ +vendor/ diff --git a/services/ResourceServiceProvider/composer.json b/services/ResourceServiceProvider/composer.json new file mode 100644 index 000000000..3fc9f5c7e --- /dev/null +++ b/services/ResourceServiceProvider/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/yaml": "^3.0" + }, + "autoload": { + "psr-4": {"Islandora\\ResourceService\\": "src/"} + }, + "authors": [ + { + "name": "Diego Pino Navarro", + "email": "dpino@krayon.cl" + } + ] +} diff --git a/services/ResourceServiceProvider/config/settings.dev.yml b/services/ResourceServiceProvider/config/settings.dev.yml new file mode 100644 index 000000000..4c88cff65 --- /dev/null +++ b/services/ResourceServiceProvider/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/ResourceServiceProvider/config/settings.yml b/services/ResourceServiceProvider/config/settings.yml new file mode 100644 index 000000000..00a4370f8 --- /dev/null +++ b/services/ResourceServiceProvider/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/ResourceServiceProvider/src/Controller/ResourceController.php b/services/ResourceServiceProvider/src/Controller/ResourceController.php new file mode 100644 index 000000000..f28db26d2 --- /dev/null +++ b/services/ResourceServiceProvider/src/Controller/ResourceController.php @@ -0,0 +1,84 @@ +query->get('tx', ""); + $metadata = $request->query->get('metadata', FALSE) ? '/fcr:metadata' : ""; + 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; + } + /** + * Resource POST route controller. 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 + */ + public function post(Application $app, Request $request, $id) { + $tx = $request->query->get('tx', ""); + $checksum = $request->query->get('checksum', ""); + 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; + } + /** + * 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. + */ + public function put(Application $app, Request $request, $id, $child) { + $tx = $request->query->get('tx', ""); + $checksum = $request->query->get('checksum', ""); + 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; + } + public function patch(Application $app, Request $request, $id, $child) { + $tx = $request->query->get('tx', ""); + 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; + } + public function delete(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; + } + +} \ No newline at end of file diff --git a/services/ResourceServiceProvider/src/Provider/ResourceServiceProvider.php b/services/ResourceServiceProvider/src/Provider/ResourceServiceProvider.php new file mode 100644 index 000000000..19526d253 --- /dev/null +++ b/services/ResourceServiceProvider/src/Provider/ResourceServiceProvider.php @@ -0,0 +1,167 @@ +share(function() use ($app) { + return new \Islandora\ResourceService\Controller\ResourceController($app); + }); + if (!isset($app['twig'])) { + $app['twig'] = $app->share($app->extend('twig', function($twig, $app) { + return $twig; + })); + } + if (!isset($app['api'])) { + $app['api'] = $app->share(function() use ($app) { + return FedoraApi::create($app['config']['islandora']['fedoraProtocol'].'://'.$app['config']['islandora']['fedoraHost'].$app['config']['islandora']['fedoraPath']); + }); + } + if (!isset($app['triplestore'])) { + $app['triplestore'] = $app->share(function() use ($app) { + return TriplestoreClient::create($app['config']['islandora']['tripleProtocol'].'://'.$app['config']['islandora']['tripleHost'].$app['config']['islandora']['triplePath']); + }); + } + /** + * Ultra simplistic YAML settings loader. + */ + if (!isset($app['config'])) { + $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; + }); + } + /** + * Make our middleware callback functions protected + */ + /** + * before middleware to handle browser requests. + */ + $app['islandora.htmlHeaderToTurtle'] = $app->protect(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); + } + }); + + + /** + * before middleware to normalize host header to same as fedora's running + * instance. + */ + $app['islandora.hostHeaderNormalize'] = $app->protect(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 + */ + $app['islandora.idToUri'] = $app->protect(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, + )); + error_log($sparql_query); + 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']; + } + }); + + } + + function boot(Application $app) { + } + + /** + * Part of ControllerProviderInterface + */ + public function connect(Application $app) { + $controllers = $app['controllers_factory']; + // + // Define routing referring to controller services + // + $controllers->get("/resource/{id}/{child}", "islandora.resourcecontroller:get") + ->convert('id', $app['islandora.idToUri']) + ->assert('id',$app['config']['islandora']['resourceIdRegex']) + ->before($app['islandora.hostHeaderNormalize']) + ->before($app['islandora.htmlHeaderToTurtle']) + ->value('id',"") + ->value('child',"") + ->bind('islandora.resourceGet'); + $controllers->post("/resource/{id}", "islandora.resourcecontroller:post") + ->convert('id', $app['islandora.idToUri']) + ->assert('id',$app['config']['islandora']['resourceIdRegex']) + ->before($app['islandora.hostHeaderNormalize']) + ->before($app['islandora.htmlHeaderToTurtle']) + ->value('id',"") + ->bind('islandora.resourcePost'); + $controllers->put("/resource/{id}/{child}", "islandora.resourcecontroller:put") + ->convert('id', $app['islandora.idToUri']) + ->assert('id',$app['config']['islandora']['resourceIdRegex']) + ->before($app['islandora.hostHeaderNormalize']) + ->before($app['islandora.htmlHeaderToTurtle']) + ->value('id',"") + ->value('child',"") + ->bind('islandora.resourcePut'); + $controllers->patch("/resource/{id}/{child}", "islandora.resourcecontroller:patch") + ->convert('id', $app['islandora.idToUri']) + ->assert('id',$app['config']['islandora']['resourceIdRegex']) + ->before($app['islandora.hostHeaderNormalize']) + ->before($app['islandora.htmlHeaderToTurtle']) + ->value('id',"") + ->value('child',"") + ->bind('islandora.resourcePatch'); + $controllers->delete("/resource/{id}/{child}", "islandora.resourcecontroller:delete") + ->convert('id', $app['islandora.idToUri']) + ->assert('id',$app['config']['islandora']['resourceIdRegex']) + ->before($app['islandora.hostHeaderNormalize']) + ->before($app['islandora.htmlHeaderToTurtle']) + ->value('id',"") + ->value('child',"") + ->bind('islandora.resourceDelete'); + return $controllers; + } +} \ No newline at end of file diff --git a/services/ResourceServiceProvider/src/index.php b/services/ResourceServiceProvider/src/index.php new file mode 100644 index 000000000..13bce78c3 --- /dev/null +++ b/services/ResourceServiceProvider/src/index.php @@ -0,0 +1,63 @@ +register(new \Silex\Provider\ServiceControllerServiceProvider()); +$app->register(new \Silex\Provider\TwigServiceProvider(), array( + 'twig.path' => __DIR__.'/../templates', +)); + +$islandoraResourceServiceProvider = new \Islandora\ResourceService\Provider\ResourceServiceProvider; + +$app->register($islandoraResourceServiceProvider); +$app->mount("/islandora", $islandoraResourceServiceProvider); + +/** + * Convert returned Guzzle responses to Symfony responses, type hinted. + */ +$app->view(function (ResponseInterface $psr7) { + return new Response($psr7->getBody(), $psr7->getStatusCode(), $psr7->getHeaders()); +}); + +$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(); diff --git a/services/ResourceServiceProvider/templates/getResourceByUUIDfromTS.sparql b/services/ResourceServiceProvider/templates/getResourceByUUIDfromTS.sparql new file mode 100644 index 000000000..b8fe9a70e --- /dev/null +++ b/services/ResourceServiceProvider/templates/getResourceByUUIDfromTS.sparql @@ -0,0 +1,5 @@ +PREFIX nfo: +PREFIX rdf: +SELECT ?s WHERE { + ?s nfo:uuid "{{uuid}}"^^ . +} From d28273a42287d25eb1375bcdd397a6a22487be94 Mon Sep 17 00:00:00 2001 From: DiegoPino Date: Wed, 20 Jan 2016 11:33:50 -0300 Subject: [PATCH 2/7] Composer update + little cleanup Added git VCS for chullo. No need to have it locally Removed a debug statement --- services/ResourceServiceProvider/composer.json | 4 ++-- .../src/Provider/ResourceServiceProvider.php | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/services/ResourceServiceProvider/composer.json b/services/ResourceServiceProvider/composer.json index 3fc9f5c7e..e96a221cc 100644 --- a/services/ResourceServiceProvider/composer.json +++ b/services/ResourceServiceProvider/composer.json @@ -4,11 +4,11 @@ "repositories": [ { "type": "vcs", - "url": "/Users/dpino/Desktop/Development/ISLANDORAWORK/CLAW_MICRO/chullo" + "url": "https://github.com/Islandora-CLAW/chullo" } ], "require": { - "islandora/chullo": "dev-api", + "islandora/chullo": "dev-master", "silex/silex": "^1.3", "symfony/config": "^3.0", "twig/twig": "^1.23", diff --git a/services/ResourceServiceProvider/src/Provider/ResourceServiceProvider.php b/services/ResourceServiceProvider/src/Provider/ResourceServiceProvider.php index 19526d253..92e6e6d84 100644 --- a/services/ResourceServiceProvider/src/Provider/ResourceServiceProvider.php +++ b/services/ResourceServiceProvider/src/Provider/ResourceServiceProvider.php @@ -89,7 +89,6 @@ function register(Application $app) { $sparql_query = $app['twig']->render('getResourceByUUIDfromTS.sparql', array( 'uuid' => $id, )); - error_log($sparql_query); try { $sparql_result = $app['triplestore']->query($sparql_query); } From ce3699cebe7d20feb63db52865fbf69e1a8cd732 Mon Sep 17 00:00:00 2001 From: DiegoPino Date: Wed, 20 Jan 2016 16:08:45 -0300 Subject: [PATCH 3/7] new Response needs capital R lazy php, more lazy diego --- services/ResourceServiceProvider/src/index.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/ResourceServiceProvider/src/index.php b/services/ResourceServiceProvider/src/index.php index 13bce78c3..518fff3be 100644 --- a/services/ResourceServiceProvider/src/index.php +++ b/services/ResourceServiceProvider/src/index.php @@ -43,20 +43,20 @@ if ($app['debug']) { return; } - return new response(sprintf('Islandora Resource Service exception: %s / HTTP %d response', $e->getMessage(), $code), $code); + 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); + 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); + return new Response(sprintf('Islandora Resource Service uncatched exception: %s %d response', $e->getMessage(), $code), $code); }); From 8ec0beff288cb78f065abcec452fc0928162003b Mon Sep 17 00:00:00 2001 From: DiegoPino Date: Fri, 22 Jan 2016 17:26:19 -0300 Subject: [PATCH 4/7] UUID provider for ResourceServiceProvier --- .../src/Provider/UUIDServiceProvider.php | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 services/ResourceServiceProvider/src/Provider/UUIDServiceProvider.php diff --git a/services/ResourceServiceProvider/src/Provider/UUIDServiceProvider.php b/services/ResourceServiceProvider/src/Provider/UUIDServiceProvider.php new file mode 100644 index 000000000..c3433fa96 --- /dev/null +++ b/services/ResourceServiceProvider/src/Provider/UUIDServiceProvider.php @@ -0,0 +1,47 @@ +share(function() use ($app) { + if (!isset($app['UuidServiceProvider.default_namespace'])) { + throw new \RuntimeException('A Default Namespace is needed to generate UUID V5'); + } + $uuid5 = Uuid::uuid5(Uuid::NAMESPACE_DNS, $app['UuidServiceProvider.default_namespace']); + return $uuid5; + }); + + $app['islandora.uuid5'] = $app->protect(function($word, $namespace = NULL) use ($app) { + if (!isset($namespace)) { + $uuid5 = Uuid::uuid5($app['islandora.baseuuid5']->toString(), $word); + } + else { + $baseuuid5 = Uuid::uuid5(Uuid::NAMESPACE_DNS, $namespace); + $uuid5 = Uuid::uuid5($baseuuid5->toString(), $word); + } + return $uuid5->toString(); + }); + + $app['islandora.uuid4'] = $app->protect(function() use ($app) { + $uuid4 = Uuid::uuid4(); + return $uuid4->toString(); + }); + } + + function boot(Application $app) { + } +} \ No newline at end of file From dd65ddca9034abd2332adb9e2dd2c37b61286b4f Mon Sep 17 00:00:00 2001 From: DiegoPino Date: Fri, 22 Jan 2016 17:26:31 -0300 Subject: [PATCH 5/7] Collection Service WIP --- services/CollectionService/.gitignore | 1 + services/CollectionService/composer.json | 31 ++++++ .../CollectionService/config/settings.dev.yml | 9 ++ .../CollectionService/config/settings.yml | 8 ++ services/CollectionService/src/index.php | 102 ++++++++++++++++++ .../createIndirectContainerfromTS.sparql | 5 + .../createPCDMCollectionfromTS.sparql | 5 + .../templates/getResourceByUUIDfromTS.sparql | 5 + .../ResourceServiceProvider/composer.json | 3 +- .../config/settings.dev.yml | 4 +- .../config/settings.yml | 4 +- 11 files changed, 174 insertions(+), 3 deletions(-) create mode 100644 services/CollectionService/.gitignore create mode 100644 services/CollectionService/composer.json create mode 100644 services/CollectionService/config/settings.dev.yml create mode 100644 services/CollectionService/config/settings.yml create mode 100644 services/CollectionService/src/index.php create mode 100644 services/CollectionService/templates/createIndirectContainerfromTS.sparql create mode 100644 services/CollectionService/templates/createPCDMCollectionfromTS.sparql create mode 100644 services/CollectionService/templates/getResourceByUUIDfromTS.sparql diff --git a/services/CollectionService/.gitignore b/services/CollectionService/.gitignore new file mode 100644 index 000000000..48b8bf907 --- /dev/null +++ b/services/CollectionService/.gitignore @@ -0,0 +1 @@ +vendor/ diff --git a/services/CollectionService/composer.json b/services/CollectionService/composer.json new file mode 100644 index 000000000..f8544c998 --- /dev/null +++ b/services/CollectionService/composer.json @@ -0,0 +1,31 @@ +{ + "name": "islandora/collection-service", + "description": "RESTful service providing resources in Fedora 4", + "repositories": [ + { + "type": "vcs", + "url": "/Users/dpino/Desktop/Development/ISLANDORAWORK/CLAW_MICRO/chullo" + }, + { + "type": "vcs", + "url": "/Users/dpino/Desktop/Development/ISLANDORAWORK/CLAW_MICRO/islandora/services/ResourceServiceProvider" + } + ], + "require": { + "islandora/chullo": "dev-api", + "islandora/resource-service" : "dev-sprint-002", + "silex/silex": "^1.3", + "symfony/config": "^3.0", + "twig/twig": "^1.23", + "symfony/yaml": "^3.0" + }, + "autoload": { + "psr-4": {"Islandora\\CollectionService\\": "src/"} + }, + "authors": [ + { + "name": "Diego Pino Navarro", + "email": "dpino@krayon.cl" + } + ] +} diff --git a/services/CollectionService/config/settings.dev.yml b/services/CollectionService/config/settings.dev.yml new file mode 100644 index 000000000..4c88cff65 --- /dev/null +++ b/services/CollectionService/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/CollectionService/config/settings.yml b/services/CollectionService/config/settings.yml new file mode 100644 index 000000000..00a4370f8 --- /dev/null +++ b/services/CollectionService/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/CollectionService/src/index.php b/services/CollectionService/src/index.php new file mode 100644 index 000000000..673d4268b --- /dev/null +++ b/services/CollectionService/src/index.php @@ -0,0 +1,102 @@ +register(new \Silex\Provider\ServiceControllerServiceProvider()); +$app->register(new \Silex\Provider\TwigServiceProvider(), array( + 'twig.path' => __DIR__.'/../templates', +)); + +$app['twig'] = $app->share($app->extend('twig', function($twig, $app) { + return $twig; +})); +$islandoraResourceServiceProvider = new \Islandora\ResourceService\Provider\ResourceServiceProvider; + +$app->register($islandoraResourceServiceProvider); +$app->mount("/islandora", $islandoraResourceServiceProvider); +$app->register(new \Islandora\ResourceService\Provider\UuidServiceProvider(), array( + 'UuidServiceProvider.default_namespace' => $app['config']['islandora']['defaultNamespaceDomainUuuidV5'], +)); + +$app['uuid'] = $app['islandora.uuid4']; + +$isFedora4Content = function (Request $request) use ($app) { + $rdf_content_types = array( + "text/turtle", + "text/rdf+n3", + "application/n3", + "text/n3", + "application/rdf+xml", + "application/n-triples", + "application/sparql-update" + ); + if (in_array($request->headers->get('Content-type'), $rdf_content_types)) { + return true; + } + return false; +} + +/** + * Convert returned Guzzle responses to Symfony responses. + */ +$app->view(function (ResponseInterface $psr7) { + return new Response($psr7->getBody(), $psr7->getStatusCode(), $psr7->getHeaders()); +}); + +/** + * 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/collection",function (Application $app, Request $request) { + + error_log($app['uuid']); + $tx = $request->query->get('tx', ""); + $url = $request->getUriForPath('/islandora/resource/'); + //static public Request create(string $uri, string $method = 'GET', array $parameters = array(), array $cookies = array(), array $files = array(), array $server = array(), string $content = null) + $subRequest = Request::create($url, 'POST', array(), $request->cookies->all(), $request->files->all(), $request->server->all()); + error_log($subRequest->__toString()); + //$response = $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false); + return "ok";//$response; +}) + +$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(); diff --git a/services/CollectionService/templates/createIndirectContainerfromTS.sparql b/services/CollectionService/templates/createIndirectContainerfromTS.sparql new file mode 100644 index 000000000..b8fe9a70e --- /dev/null +++ b/services/CollectionService/templates/createIndirectContainerfromTS.sparql @@ -0,0 +1,5 @@ +PREFIX nfo: +PREFIX rdf: +SELECT ?s WHERE { + ?s nfo:uuid "{{uuid}}"^^ . +} diff --git a/services/CollectionService/templates/createPCDMCollectionfromTS.sparql b/services/CollectionService/templates/createPCDMCollectionfromTS.sparql new file mode 100644 index 000000000..b8fe9a70e --- /dev/null +++ b/services/CollectionService/templates/createPCDMCollectionfromTS.sparql @@ -0,0 +1,5 @@ +PREFIX nfo: +PREFIX rdf: +SELECT ?s WHERE { + ?s nfo:uuid "{{uuid}}"^^ . +} diff --git a/services/CollectionService/templates/getResourceByUUIDfromTS.sparql b/services/CollectionService/templates/getResourceByUUIDfromTS.sparql new file mode 100644 index 000000000..b8fe9a70e --- /dev/null +++ b/services/CollectionService/templates/getResourceByUUIDfromTS.sparql @@ -0,0 +1,5 @@ +PREFIX nfo: +PREFIX rdf: +SELECT ?s WHERE { + ?s nfo:uuid "{{uuid}}"^^ . +} diff --git a/services/ResourceServiceProvider/composer.json b/services/ResourceServiceProvider/composer.json index e96a221cc..a79b8e6d9 100644 --- a/services/ResourceServiceProvider/composer.json +++ b/services/ResourceServiceProvider/composer.json @@ -12,7 +12,8 @@ "silex/silex": "^1.3", "symfony/config": "^3.0", "twig/twig": "^1.23", - "symfony/yaml": "^3.0" + "symfony/yaml": "^3.0", + "ramsey/uuid": "^3.1" }, "autoload": { "psr-4": {"Islandora\\ResourceService\\": "src/"} diff --git a/services/ResourceServiceProvider/config/settings.dev.yml b/services/ResourceServiceProvider/config/settings.dev.yml index 4c88cff65..5f0ca8418 100644 --- a/services/ResourceServiceProvider/config/settings.dev.yml +++ b/services/ResourceServiceProvider/config/settings.dev.yml @@ -6,4 +6,6 @@ islandora: 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 + resourceIdRegex: "(?:[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})?" +# This domain is used as namespace (hashed) when generating UUID V5 identifiers + defaultNamespaceDomainUuuidV5: "www.islandora.ca" \ No newline at end of file diff --git a/services/ResourceServiceProvider/config/settings.yml b/services/ResourceServiceProvider/config/settings.yml index 00a4370f8..579f83fbe 100644 --- a/services/ResourceServiceProvider/config/settings.yml +++ b/services/ResourceServiceProvider/config/settings.yml @@ -5,4 +5,6 @@ islandora: 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 + resourceIdRegex: "(?:[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})?" + # This domain is used as namespace (hashed) when generating UUID V5 identifiers, replace with your own + defaultNamespaceDomainUuuidV5: "www.islandora.ca" \ No newline at end of file From ff2750c7cf96dd42080c14e799553e6c59aed1ab Mon Sep 17 00:00:00 2001 From: DiegoPino Date: Fri, 22 Jan 2016 18:08:44 -0300 Subject: [PATCH 6/7] Changed to PATH type on repositories composer We have a monolithic project, git gets crazy in composer. Lets use path for now. Must be tuned during testing to local path. Before final merging will add real git. --- services/CollectionService/composer.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/services/CollectionService/composer.json b/services/CollectionService/composer.json index f8544c998..c2503ea9b 100644 --- a/services/CollectionService/composer.json +++ b/services/CollectionService/composer.json @@ -3,16 +3,17 @@ "description": "RESTful service providing resources in Fedora 4", "repositories": [ { - "type": "vcs", - "url": "/Users/dpino/Desktop/Development/ISLANDORAWORK/CLAW_MICRO/chullo" + "type": "vcs", + "url": "https://github.com/Islandora-CLAW/chullo" + }, { - "type": "vcs", + "type": "path", "url": "/Users/dpino/Desktop/Development/ISLANDORAWORK/CLAW_MICRO/islandora/services/ResourceServiceProvider" } ], "require": { - "islandora/chullo": "dev-api", + "islandora/chullo": "dev-master", "islandora/resource-service" : "dev-sprint-002", "silex/silex": "^1.3", "symfony/config": "^3.0", From fae371c7af82bf0801549ae46ca317905cd962b1 Mon Sep 17 00:00:00 2001 From: DiegoPino Date: Fri, 22 Jan 2016 18:10:40 -0300 Subject: [PATCH 7/7] Added some info to this test service Collection Service does nothing. But it allows to do anything. Whole remote serviceprovider/controllerprovider logic is working perfect, also UUID4 (and swappable V5 also). Test route transforms a post to collection into an internal GET to resource. Some debug error_log in place to see what is happening. Pretty happy! --- services/CollectionService/src/index.php | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/services/CollectionService/src/index.php b/services/CollectionService/src/index.php index 673d4268b..2ac74cb18 100644 --- a/services/CollectionService/src/index.php +++ b/services/CollectionService/src/index.php @@ -36,8 +36,12 @@ 'UuidServiceProvider.default_namespace' => $app['config']['islandora']['defaultNamespaceDomainUuuidV5'], )); +//$app['uuid'] = $app['islandora.uuid5'](rand()); $app['uuid'] = $app['islandora.uuid4']; +/** + * Still Not used, this function will check for content type +*/ $isFedora4Content = function (Request $request) use ($app) { $rdf_content_types = array( "text/turtle", @@ -52,31 +56,31 @@ return true; } return false; -} +}; /** * Convert returned Guzzle responses to Symfony responses. */ + $app->view(function (ResponseInterface $psr7) { return new Response($psr7->getBody(), $psr7->getStatusCode(), $psr7->getHeaders()); }); /** - * Resource POST route. takes $id (valid UUID or empty) for the parent resource as first value to match + * Collection POST route test. Does nothing more than redirect from collection to mounted * takes 'rx' and/or 'checksum' as optional query arguments - * @see https://wiki.duraspace.org/display/FEDORA40/RESTful+HTTP+API#RESTfulHTTPAPI-BluePOSTCreatenewresourceswithinaLDPcontainer */ $app->post("/islandora/collection",function (Application $app, Request $request) { - error_log($app['uuid']); $tx = $request->query->get('tx', ""); $url = $request->getUriForPath('/islandora/resource/'); + error_log($url); //static public Request create(string $uri, string $method = 'GET', array $parameters = array(), array $cookies = array(), array $files = array(), array $server = array(), string $content = null) - $subRequest = Request::create($url, 'POST', array(), $request->cookies->all(), $request->files->all(), $request->server->all()); + $subRequest = Request::create($url, 'GET', array(), $request->cookies->all(), $request->files->all(), $request->server->all()); error_log($subRequest->__toString()); - //$response = $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false); - return "ok";//$response; -}) + $response = $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false); + return $response; +}); $app->error(function (\Symfony\Component\HttpKernel\Exception\HttpException $e, $code) use ($app){ if ($app['debug']) {