From 60edf61a72bcc31f38201ba14e9a7cab75b87b14 Mon Sep 17 00:00:00 2001 From: DiegoPino Date: Thu, 11 Feb 2016 10:27:44 -0300 Subject: [PATCH 1/5] Collection Service Implementation Implements Collection Service with RDF aggregator. Clean up of composer.json to use 0.0.2 chullo package Allows Resource Service Config yaml files to be overridden by implementing app Adds a common route collection to ResourceService unifying some middleware --- services/CollectionService/composer.json | 23 +-- .../CollectionService/config/settings.dev.yml | 5 +- .../CollectionService/config/settings.yml | 5 +- services/CollectionService/src/index.php | 159 ++++++++++++------ .../createIndirectContainerfromTS.sparql | 5 - .../createIndirectContainerfromTS.ttl | 8 + .../createPCDMCollectionfromTS.sparql | 5 - .../ResourceServiceProvider/composer.json | 8 +- .../config/settings.yml | 2 +- .../src/Provider/ResourceServiceProvider.php | 56 +++--- 10 files changed, 161 insertions(+), 115 deletions(-) delete mode 100644 services/CollectionService/templates/createIndirectContainerfromTS.sparql create mode 100644 services/CollectionService/templates/createIndirectContainerfromTS.ttl delete mode 100644 services/CollectionService/templates/createPCDMCollectionfromTS.sparql diff --git a/services/CollectionService/composer.json b/services/CollectionService/composer.json index c2503ea9b..b2ec95bd3 100644 --- a/services/CollectionService/composer.json +++ b/services/CollectionService/composer.json @@ -1,24 +1,19 @@ { "name": "islandora/collection-service", - "description": "RESTful service providing resources in Fedora 4", - "repositories": [ - { - "type": "vcs", - "url": "https://github.com/Islandora-CLAW/chullo" - - }, - { - "type": "path", - "url": "/Users/dpino/Desktop/Development/ISLANDORAWORK/CLAW_MICRO/islandora/services/ResourceServiceProvider" - } - ], + "description": "RESTful service providing PCDM Collections in Fedora 4", + "repositories": [{ + "type": "path", + "url": "../ResourceServiceProvider" + }], "require": { - "islandora/chullo": "dev-master", + "islandora/chullo": "^0.0", "islandora/resource-service" : "dev-sprint-002", "silex/silex": "^1.3", "symfony/config": "^3.0", "twig/twig": "^1.23", - "symfony/yaml": "^3.0" + "symfony/yaml": "^3.0", + "easyrdf/easyrdf": "^0.9.1", + "ml/json-ld": "^1.0" }, "autoload": { "psr-4": {"Islandora\\CollectionService\\": "src/"} diff --git a/services/CollectionService/config/settings.dev.yml b/services/CollectionService/config/settings.dev.yml index 4c88cff65..129b9ad2d 100644 --- a/services/CollectionService/config/settings.dev.yml +++ b/services/CollectionService/config/settings.dev.yml @@ -1,9 +1,12 @@ # Islandora Dev Settings to be used with $app['debug'] == TRUE islandora: + apiVersion: 0.0.1 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 + 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 diff --git a/services/CollectionService/config/settings.yml b/services/CollectionService/config/settings.yml index 00a4370f8..d68af0eda 100644 --- a/services/CollectionService/config/settings.yml +++ b/services/CollectionService/config/settings.yml @@ -1,8 +1,11 @@ islandora: + apiVersion: 0.0.1 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 + 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 diff --git a/services/CollectionService/src/index.php b/services/CollectionService/src/index.php index 2ac74cb18..880b82390 100644 --- a/services/CollectionService/src/index.php +++ b/services/CollectionService/src/index.php @@ -5,15 +5,12 @@ require_once __DIR__.'/../vendor/autoload.php'; use Silex\Application; -use Islandora\Chullo\FedoraApi; -use Islandora\Chullo\TriplestoreClient; use Islandora\ResourceService\Provider\ResourceServiceProvider; 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\Component\Yaml\Yaml; date_default_timezone_set('UTC'); @@ -25,39 +22,24 @@ '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); +//Registers Resource Service and defines current app's path for config context +$app->register($islandoraResourceServiceProvider, array( + 'islandora.BasePath' => __DIR__, +)); $app->mount("/islandora", $islandoraResourceServiceProvider); $app->register(new \Islandora\ResourceService\Provider\UuidServiceProvider(), array( 'UuidServiceProvider.default_namespace' => $app['config']['islandora']['defaultNamespaceDomainUuuidV5'], )); -//$app['uuid'] = $app['islandora.uuid5'](rand()); +//We will use a static uuid5 to fake a real IRI to replace <> during turtle parsing +$app['uuid5'] = $app->share(function () use ($app) { + return $app['islandora.uuid5']($app['config']['islandora']['fedoraProtocol'].'://'.$app['config']['islandora']['fedoraHost'].$app['config']['islandora']['fedoraPath']); +}); +//This is the uuidV4 generator $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", - "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. */ @@ -67,40 +49,123 @@ }); /** - * Collection POST route test. Does nothing more than redirect from collection to mounted - * takes 'rx' and/or 'checksum' as optional query arguments + * Collection POST route. takes $id (valid UUID or empty) for the parent resource as first value to match + * takes 'rx' as optional query arguments */ -$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, 'GET', array(), $request->cookies->all(), $request->files->all(), $request->server->all()); - error_log($subRequest->__toString()); - $response = $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false); - return $response; +$app->post("/islandora/collection/{id}", function (Request $request, $id) use ($app) { + $tx = $request->query->get('tx', ""); + //Check for format + $format = NULL; + try { + $format = \EasyRdf_Format::getFormat($request->headers->get('Content-Type')); + } catch (\EasyRdf_Exception $e) { + $app->abort(415, $e->getMessage()); + } + + //Now check if body can be parsed in that format + if ($format) { //EasyRdf_Format + //@see http://www.w3.org/2011/rdfa-context/rdfa-1.1 for defaults + \EasyRdf_Namespace::set('pcdm', 'http://pcdm.org/models#'); + \EasyRdf_Namespace::set('nfo', 'http://www.semanticdesktop.org/ontologies/2007/03/22/nfo/v1.1/'); + \EasyRdf_Namespace::set('isl', 'http://www.islandora.ca/ontologies/2016/02/28/isl/v1.0/'); + \EasyRdf_Namespace::set('ldp', 'http://www.w3.org/ns/ldp'); + + //Fake IRI, default LDP one for current resource "<>" is not a valid IRI! + $fakeIri = new \EasyRdf_ParsedUri('urn:uuid:'.$app['uuid5']); + + $graph = new \EasyRdf_Graph(); + try { + $graph->parse($request->getContent(), $format->getName(), $fakeIri); + } catch (\EasyRdf_Exception $e) { + $app->abort(415, $e->getMessage()); + } + //Add a pcmd:Collection type + $graph->resource($fakeIri, 'pcdm:Collection'); + + //Check if we got an UUID inside posted RDF. We won't validate it here because it's the caller responsability + if (NULL != $graph->countValues($fakeIri, '')) { + $existingUuid = $graph->getLiteral($uri, ''); + $graph->addResource($fakeIri, 'http://www.islandora.ca/ontologies/2016/02/28/isl/v1.0/hasURN', 'urn:uuid:'.$existingUuid); //Testing an Islandora Ontology! + } else { + //No UUID from the caller in RDF, lets put something there + $tmpUuid = $app['uuid']; //caching here, since it's regenerated each time it is used and I need the same twice + $graph->addLiteral($fakeIri,"http://www.semanticdesktop.org/ontologies/2007/03/22/nfo/v1.1/uuid",$tmpUuid); //Keeps compat for now with other services + $graph->addResource($fakeIri,"http://www.islandora.ca/ontologies/2016/02/28/isl/v1.0/hasURN",'urn:uuid:'.$tmpUuid); //Testing an Islandora Ontology + } + //Restore LDP <> IRI on serialised graph + $pcmd_collection_rdf= preg_replace('/'.$fakeIri.'/', '', $graph->serialise('turtle')); + } + + $urlRoute = $request->getUriForPath('/islandora/resource/'); + $request->headers->set('Content-Type', 'text/turtle'); + $subRequestPost = Request::create($urlRoute.$id, 'POST', array(), $request->cookies->all(), $request->files->all(), $request->server->all(), $pcmd_collection_rdf); + $subRequestPost->query->set('tx', $tx); + $responsePost = $app->handle($subRequestPost, HttpKernelInterface::SUB_REQUEST, false); + + if (201 == $responsePost->getStatusCode()) {// OK, collection created + //Lets take the location header in the response + $indirect_container_rdf = $app['twig']->render('createIndirectContainerfromTS.ttl', array( + 'resource' => $responsePost->headers->get('location'), + )); + + $subRequestPut = Request::create($urlRoute.$id, 'PUT', array(), $request->cookies->all(), array(), $request->server->all(), $indirect_container_rdf); + $subRequestPut->query->set('tx', $tx); + $subRequestPut->headers->set('Slug', 'members'); + //Can't use in middleware, but needed. Without Fedora 4 throws big java errors! + $subRequestPut->headers->set('Host', $app['config']['islandora']['fedoraHost'], TRUE); + //Here is the thing. We don't know if UUID of the collection we just created is already in the tripple store. + //So what to do? We could just try to use our routes directly, but UUID check agains triplestore we could fail! + //lets invoke the controller method directly + $responsePut = $app['islandora.resourcecontroller']->put($app, $subRequestPut, $responsePost->headers->get('location'), "members"); + if (201 == $responsePut->getStatusCode()) {// OK, indirect container created + //Return only the last created resource + $putHeaders = $responsePut->getHeaders(); + //Guzzle psr7 response objects are inmutable. So we have to make this an array and add directly + $putHeaders['Link'] = array('<'.$urlRoute.$tmpUuid.'/members>; rel="alternate"'); + + return new Response($responsePut->getBody(), 200, $putHeaders); + } + + return $responsePut; + } + //Abort if PCDM collection object could not be created + $app->abort($responsePost->getStatusCode(), 'Failed creating PCDM Collection'); +}) +->value('id',""); + +$app->after(function (Request $request, Response $response) use ($app) { + $response->headers->set('X-Powered-By', 'Islandora Collection REST API v'.$app['config']['islandora']['apiVersion'], TRUE); //Nice + }); -$app->error(function (\Symfony\Component\HttpKernel\Exception\HttpException $e, $code) use ($app){ +//Common error Handling +$app->error(function (\EasyRdf_Exception $e, $code) use ($app) { if ($app['debug']) { return; } - return new response(sprintf('Islandora Resource Service exception: %s / HTTP %d response', $e->getMessage(), $code), $code); + + return new response(sprintf('RDF Library exception', $e->getMessage(), $code), $code); }); -$app->error(function (\Symfony\Component\HttpKernel\Exception\NotFoundHttpException $e, $code) use ($app){ +$app->error(function (\Symfony\Component\HttpKernel\Exception\HttpException $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 Collection Service exception: %s / HTTP %d response', $e->getMessage(), $code), $code); }); -$app->error(function (\Exception $e, $code) use ($app){ +$app->error(function (\Symfony\Component\HttpKernel\Exception\NotFoundHttpException $e, $code) use ($app) { if ($app['debug']) { return; - } - return new response(sprintf('Islandora Resource Service uncatched exception: %s %d response', $e->getMessage(), $code), $code); + } + //Not sure what the best "verbose" message is + return new response(sprintf('Islandora Collection 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 Collection 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 deleted file mode 100644 index b8fe9a70e..000000000 --- a/services/CollectionService/templates/createIndirectContainerfromTS.sparql +++ /dev/null @@ -1,5 +0,0 @@ -PREFIX nfo: -PREFIX rdf: -SELECT ?s WHERE { - ?s nfo:uuid "{{uuid}}"^^ . -} diff --git a/services/CollectionService/templates/createIndirectContainerfromTS.ttl b/services/CollectionService/templates/createIndirectContainerfromTS.ttl new file mode 100644 index 000000000..219b8aa74 --- /dev/null +++ b/services/CollectionService/templates/createIndirectContainerfromTS.ttl @@ -0,0 +1,8 @@ +@prefix ldp: . +@prefix pcdm: . +@prefix ore: . + +<> a ldp:IndirectContainer ; + ldp:membershipResource <{{ resource }}> ; + ldp:hasMemberRelation pcdm:hasMember ; + ldp:insertedContentRelation ore:proxyFor . \ No newline at end of file diff --git a/services/CollectionService/templates/createPCDMCollectionfromTS.sparql b/services/CollectionService/templates/createPCDMCollectionfromTS.sparql deleted file mode 100644 index b8fe9a70e..000000000 --- a/services/CollectionService/templates/createPCDMCollectionfromTS.sparql +++ /dev/null @@ -1,5 +0,0 @@ -PREFIX nfo: -PREFIX rdf: -SELECT ?s WHERE { - ?s nfo:uuid "{{uuid}}"^^ . -} diff --git a/services/ResourceServiceProvider/composer.json b/services/ResourceServiceProvider/composer.json index a79b8e6d9..f68d44bff 100644 --- a/services/ResourceServiceProvider/composer.json +++ b/services/ResourceServiceProvider/composer.json @@ -1,14 +1,8 @@ { "name": "islandora/resource-service", "description": "RESTful service providing resources in Fedora 4", - "repositories": [ - { - "type": "vcs", - "url": "https://github.com/Islandora-CLAW/chullo" - } - ], "require": { - "islandora/chullo": "dev-master", + "islandora/chullo": "^0.0", "silex/silex": "^1.3", "symfony/config": "^3.0", "twig/twig": "^1.23", diff --git a/services/ResourceServiceProvider/config/settings.yml b/services/ResourceServiceProvider/config/settings.yml index 579f83fbe..ee4b9c28b 100644 --- a/services/ResourceServiceProvider/config/settings.yml +++ b/services/ResourceServiceProvider/config/settings.yml @@ -6,5 +6,5 @@ islandora: 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})?" - # This domain is used as namespace (hashed) when generating UUID V5 identifiers, replace with your own +# 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 diff --git a/services/ResourceServiceProvider/src/Provider/ResourceServiceProvider.php b/services/ResourceServiceProvider/src/Provider/ResourceServiceProvider.php index 92e6e6d84..7746cfbb3 100644 --- a/services/ResourceServiceProvider/src/Provider/ResourceServiceProvider.php +++ b/services/ResourceServiceProvider/src/Provider/ResourceServiceProvider.php @@ -22,6 +22,9 @@ function register(Application $app) { // // Define controller services // + //This is the base path for the application. Used to change the location + //of yaml config files when registerd somewhere else + $app['islandora.BasePath'] = __DIR__.'/..'; $app['islandora.resourcecontroller'] = $app->share(function() use ($app) { return new \Islandora\ResourceService\Controller\ResourceController($app); }); @@ -45,12 +48,14 @@ function register(Application $app) { */ 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'; - } + { + if ($app['debug']) { + $configFile = $app['islandora.BasePath'].'/../config/settings.dev.yml'; + } + else { + $configFile = $app['islandora.BasePath'].'/../config/settings.yml'; + } + } $settings = Yaml::parse(file_get_contents($configFile)); return $settings; }); @@ -118,49 +123,32 @@ function boot(Application $app) { * Part of ControllerProviderInterface */ public function connect(Application $app) { - $controllers = $app['controllers_factory']; + $ResourceControllers = $app['controllers_factory']; // // Define routing referring to controller services // - $controllers->get("/resource/{id}/{child}", "islandora.resourcecontroller:get") + $ResourceControllers ->convert('id', $app['islandora.idToUri']) ->assert('id',$app['config']['islandora']['resourceIdRegex']) ->before($app['islandora.hostHeaderNormalize']) ->before($app['islandora.htmlHeaderToTurtle']) - ->value('id',"") + ->value('id',""); + + + $ResourceControllers->get("/resource/{id}/{child}", "islandora.resourcecontroller:get") ->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',"") + $ResourceControllers->post("/resource/{id}", "islandora.resourcecontroller:post") ->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',"") + $ResourceControllers->put("/resource/{id}/{child}", "islandora.resourcecontroller:put") ->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',"") + $ResourceControllers->patch("/resource/{id}/{child}", "islandora.resourcecontroller:patch") ->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',"") + $ResourceControllers->delete("/resource/{id}/{child}", "islandora.resourcecontroller:delete") ->value('child',"") ->bind('islandora.resourceDelete'); - return $controllers; + return $ResourceControllers; } } \ No newline at end of file From 2bf3e906a14d0006f14955fca95c7c7c884a980e Mon Sep 17 00:00:00 2001 From: DiegoPino Date: Thu, 11 Feb 2016 11:13:12 -0300 Subject: [PATCH 2/5] Defaults for Content-type Header In case Content-type is empty default to text/turtle. Important even when nothing is passed in the body --- services/CollectionService/src/index.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/services/CollectionService/src/index.php b/services/CollectionService/src/index.php index 880b82390..1536beddf 100644 --- a/services/CollectionService/src/index.php +++ b/services/CollectionService/src/index.php @@ -54,10 +54,12 @@ */ $app->post("/islandora/collection/{id}", function (Request $request, $id) use ($app) { $tx = $request->query->get('tx', ""); + + //Check for format $format = NULL; try { - $format = \EasyRdf_Format::getFormat($request->headers->get('Content-Type')); + $format = \EasyRdf_Format::getFormat($contentType = $request->headers->get('Content-Type', 'text/turtle')); } catch (\EasyRdf_Exception $e) { $app->abort(415, $e->getMessage()); } @@ -84,7 +86,7 @@ //Check if we got an UUID inside posted RDF. We won't validate it here because it's the caller responsability if (NULL != $graph->countValues($fakeIri, '')) { - $existingUuid = $graph->getLiteral($uri, ''); + $existingUuid = $graph->getLiteral($fakeIri, ''); $graph->addResource($fakeIri, 'http://www.islandora.ca/ontologies/2016/02/28/isl/v1.0/hasURN', 'urn:uuid:'.$existingUuid); //Testing an Islandora Ontology! } else { //No UUID from the caller in RDF, lets put something there @@ -97,9 +99,10 @@ } $urlRoute = $request->getUriForPath('/islandora/resource/'); - $request->headers->set('Content-Type', 'text/turtle'); - $subRequestPost = Request::create($urlRoute.$id, 'POST', array(), $request->cookies->all(), $request->files->all(), $request->server->all(), $pcmd_collection_rdf); + + $subRequestPost = Request::create($urlRoute.$id, 'POST', array(), $request->cookies->all(), array(), $request->server->all(), $pcmd_collection_rdf); $subRequestPost->query->set('tx', $tx); + $subRequestPost->headers->set('Content-Type', 'text/turtle'); $responsePost = $app->handle($subRequestPost, HttpKernelInterface::SUB_REQUEST, false); if (201 == $responsePost->getStatusCode()) {// OK, collection created @@ -113,6 +116,7 @@ $subRequestPut->headers->set('Slug', 'members'); //Can't use in middleware, but needed. Without Fedora 4 throws big java errors! $subRequestPut->headers->set('Host', $app['config']['islandora']['fedoraHost'], TRUE); + $subRequestPut->headers->set('Content-Type', 'text/turtle'); //Here is the thing. We don't know if UUID of the collection we just created is already in the tripple store. //So what to do? We could just try to use our routes directly, but UUID check agains triplestore we could fail! //lets invoke the controller method directly From c7aa759cbe6376549baef7bdf51c1eab9119c1de Mon Sep 17 00:00:00 2001 From: DiegoPino Date: Thu, 11 Feb 2016 13:59:16 -0300 Subject: [PATCH 3/5] Change Route Comment wording Thanks to good @ruebot suggestion. --- services/CollectionService/src/index.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/services/CollectionService/src/index.php b/services/CollectionService/src/index.php index 1536beddf..4e35cd705 100644 --- a/services/CollectionService/src/index.php +++ b/services/CollectionService/src/index.php @@ -49,13 +49,13 @@ }); /** - * Collection POST route. takes $id (valid UUID or empty) for the parent resource as first value to match - * takes 'rx' as optional query arguments + * Collection POST route. + * Takes $id (valid UUID or empty) for the parent resource as first value to match, + * and also takes 'rx' as an optional query argument. */ $app->post("/islandora/collection/{id}", function (Request $request, $id) use ($app) { $tx = $request->query->get('tx', ""); - - + //Check for format $format = NULL; try { From 043a0e1d4b3781a0d56dd4b907288d9a5843e54f Mon Sep 17 00:00:00 2001 From: DiegoPino Date: Thu, 11 Feb 2016 14:21:28 -0300 Subject: [PATCH 4/5] Changed to str_replace According to @daniel-dgi suggestion. I hope i did not break anything! --- services/CollectionService/src/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/CollectionService/src/index.php b/services/CollectionService/src/index.php index 4e35cd705..6b3cd779b 100644 --- a/services/CollectionService/src/index.php +++ b/services/CollectionService/src/index.php @@ -95,7 +95,7 @@ $graph->addResource($fakeIri,"http://www.islandora.ca/ontologies/2016/02/28/isl/v1.0/hasURN",'urn:uuid:'.$tmpUuid); //Testing an Islandora Ontology } //Restore LDP <> IRI on serialised graph - $pcmd_collection_rdf= preg_replace('/'.$fakeIri.'/', '', $graph->serialise('turtle')); + $pcmd_collection_rdf= str_replace($fakeIri, '', $graph->serialise('turtle')); } $urlRoute = $request->getUriForPath('/islandora/resource/'); From e2ff5e6754dfb8845a7727f46c6524b687d3aee7 Mon Sep 17 00:00:00 2001 From: DiegoPino Date: Fri, 12 Feb 2016 14:02:51 -0300 Subject: [PATCH 5/5] Fix response CODE -> 201 @whikloj thanks for catching this --- services/CollectionService/src/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/CollectionService/src/index.php b/services/CollectionService/src/index.php index 6b3cd779b..50c331e85 100644 --- a/services/CollectionService/src/index.php +++ b/services/CollectionService/src/index.php @@ -127,7 +127,7 @@ //Guzzle psr7 response objects are inmutable. So we have to make this an array and add directly $putHeaders['Link'] = array('<'.$urlRoute.$tmpUuid.'/members>; rel="alternate"'); - return new Response($responsePut->getBody(), 200, $putHeaders); + return new Response($responsePut->getBody(), 201, $putHeaders); } return $responsePut;