diff --git a/.gitignore b/.gitignore index 5f92d46db..3aeca7a50 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ tests/test_config.ini install/.vagrant install/downloads site/ +installer +composer.phar +vendor -services/ResourceService/composer.lock - -services/ResourceServiceProvider/composer.lock diff --git a/camel/pom.xml b/camel/pom.xml index c323bd962..3642d4fa4 100644 --- a/camel/pom.xml +++ b/camel/pom.xml @@ -37,7 +37,6 @@ sync - services component karaf diff --git a/install/Vagrantfile b/install/Vagrantfile index 3ae82376e..d6afd811d 100644 --- a/install/Vagrantfile +++ b/install/Vagrantfile @@ -51,6 +51,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.network :forwarded_port, guest: 8080, host: 8080 # Tomcat config.vm.network :forwarded_port, guest: 8181, host: 8181 # Karaf + config.vm.network :forwarded_port, guest: 8282, host: 8282 # Islandora Microservices config.vm.network :forwarded_port, guest: 3306, host: 3306 # MySQL config.vm.network :forwarded_port, guest: 5432, host: 5432 # PostgreSQL @@ -70,4 +71,5 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.provision :shell, :path => "./scripts/islandora-karaf-components.sh", :args => home_dir config.vm.provision :shell, :path => "./scripts/config.sh", :args => home_dir config.vm.provision :shell, :path => "./scripts/post-install.sh", :args => home_dir + config.vm.provision :shell, :path => "./scripts/islandora-microservices.sh", :args => home_dir end diff --git a/install/configs/001-microservices.conf b/install/configs/001-microservices.conf new file mode 100644 index 000000000..4683f6a97 --- /dev/null +++ b/install/configs/001-microservices.conf @@ -0,0 +1,47 @@ + + # The ServerName directive sets the request scheme, hostname and port that + # the server uses to identify itself. This is used when creating + # redirection URLs. In the context of virtual hosts, the ServerName + # specifies what hostname must appear in the request's Host: header to + # match this virtual host. For the default virtual host (this file) this + # value is not decisive as it is used as a last resort host regardless. + # However, you must set it for any further virtual host explicitly. + #ServerName www.example.com + + ServerAdmin webmaster@localhost + DocumentRoot /opt/islandora/services/src + + + Options Indexes FollowSymLinks MultiViews + AllowOverride All + Order allow,deny + Allow from all + Require all granted + + + + RewriteEngine On + # RewriteBase /src + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule ^ /index.php [QSA,L] + + + # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, + # error, crit, alert, emerg. + # It is also possible to configure the loglevel for particular + # modules, e.g. + #LogLevel info ssl:warn + #LogLevel info rewrite:trace3 + LogLevel info + + ErrorLog ${APACHE_LOG_DIR}/services-error.log + CustomLog ${APACHE_LOG_DIR}/services-access.log combined + + # For most configuration files from conf-available/, which are + # enabled or disabled at a global level, it is possible to + # include a line for only one particular virtual host. For example the + # following line enables the CGI configuration for this host only + # after it has been globally disabled with "a2disconf". + #Include conf-available/serve-cgi-bin.conf + \ No newline at end of file diff --git a/install/configs/karaf/watch.script b/install/configs/karaf/watch.script index e485ccf31..32474fbe0 100644 --- a/install/configs/karaf/watch.script +++ b/install/configs/karaf/watch.script @@ -1,5 +1,3 @@ bundle:watch --start mvn:ca.islandora.camel.component/islandora-camel-component/0.0.1-SNAPSHOT bundle:watch --start mvn:ca.islandora.camel.sync/islandora-sync-gateway/0.0.1-SNAPSHOT -bundle:watch --start mvn:ca.islandora.camel.services/islandora-collection-service/0.0.1-SNAPSHOT -bundle:watch --start mvn:ca.islandora.camel.services/islandora-basic-image-service/0.0.1-SNAPSHOT logout diff --git a/install/scripts/align_branches.sh b/install/scripts/align_branches.sh new file mode 100755 index 000000000..a98d9d3b7 --- /dev/null +++ b/install/scripts/align_branches.sh @@ -0,0 +1,18 @@ +#!/bin/sh +# whikloj - 2016-03-22 +# +# Changes the version for islandora/resource-service or +# islandora/transaction-service to 'dev-' + +# Currently selected branch in git +CURRENT_BRANCH=$(git branch | grep '*' | cut -d' ' -f2) +# List of directories to change composer.json in +AFFECTS_DIR=". CollectionService TransactionService" + +echo "Altering composer.json to use branch 'dev-${CURRENT_BRANCH}'..." +for i in $AFFECTS_DIR; do + mv $i/composer.json $i/composer.json_bkup + awk -v BRANCH=$CURRENT_BRANCH '/islandora\/(resource|transaction|collection)/ { print gensub(/(.+):\s*"dev-[^"]+/, "\\1: \"dev-"BRANCH, 1)} !/islandora\/(resource|transaction|collection)/ { print $0}' $i/composer.json_bkup > $i/composer.json +done +echo "Done" + diff --git a/install/scripts/drupal.sh b/install/scripts/drupal.sh old mode 100644 new mode 100755 diff --git a/install/scripts/islandora-karaf-components.sh b/install/scripts/islandora-karaf-components.sh old mode 100644 new mode 100755 index 4020bb5c0..82f551f5d --- a/install/scripts/islandora-karaf-components.sh +++ b/install/scripts/islandora-karaf-components.sh @@ -9,9 +9,3 @@ fi echo "Installing Islandora Sync Gateway" $KARAF_CLIENT -f $KARAF_CONFIGS/islandora_sync_gateway.script -sleep 10 -echo "Installing Islandora Basic Image Service" -$KARAF_CLIENT -f $KARAF_CONFIGS/islandora_basic_image.script -sleep 10 -echo "Installing Islandora Collection Service" -$KARAF_CLIENT -f $KARAF_CONFIGS/islandora_collection.script diff --git a/install/scripts/islandora-microservices.sh b/install/scripts/islandora-microservices.sh new file mode 100755 index 000000000..7d94fec44 --- /dev/null +++ b/install/scripts/islandora-microservices.sh @@ -0,0 +1,28 @@ +#!/bin/sh +echo "Installing Composer and Islandora Microservices" + +HOME_DIR=$1 +if [ -f "$HOME_DIR/islandora/install/configs/variables" ]; then + . "$HOME_DIR"/islandora/install/configs/variables +fi + +ln -s "$HOME_DIR/islandora" "/opt/islandora" + +cp "$HOME_DIR/islandora/install/configs/001-microservices.conf" "/etc/apache2/sites-enabled/" + +if [ $(grep -c 'Listen 8282' /etc/apache2/ports.conf) != 1 ]; then + echo "Adding Listen 8282 to Apache ports.conf" + sed -i '/Listen 80$/a \Listen 8282' /etc/apache2/ports.conf +fi + +/etc/init.d/apache2 restart + +cp "$HOME_DIR/islandora/install/scripts/align_branches.sh" "/opt/islandora/services" +cd /opt/islandora/services +./align_branches.sh + +php -r "readfile('https://getcomposer.org/installer');" > composer-setup.php +php -r "if (hash('SHA384', file_get_contents('composer-setup.php')) === '41e71d86b40f28e771d4bb662b997f79625196afcca95a5abf44391188c695c6c1456e16154c75a211d238cc3bc5cb47') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" +php composer-setup.php +php -r "unlink('composer-setup.php');" +php composer.phar update diff --git a/services/CollectionService/composer.json b/services/CollectionService/composer.json index b01752e9c..66e0868c8 100644 --- a/services/CollectionService/composer.json +++ b/services/CollectionService/composer.json @@ -4,10 +4,15 @@ "repositories": [{ "type": "path", "url": "../ResourceService" + }, + { + "type": "path", + "url": "../TransactionService" }], "require": { "islandora/chullo": "^0.0", - "islandora/resource-service" : "dev-sprint-002", + "islandora/resource-service" : "dev-sprint-002-working-vagrant", + "islandora/transaction-service" : "dev-sprint-002-working-vagrant", "silex/silex": "^1.3", "symfony/config": "^3.0", "twig/twig": "^1.23", @@ -22,6 +27,10 @@ { "name": "Diego Pino Navarro", "email": "dpino@krayon.cl" + }, + { + "name": "Jared Whiklo", + "email": "jwhiklo@gmail.com" } ] } diff --git a/services/CollectionService/composer.lock b/services/CollectionService/composer.lock index 54500af76..eb88f650f 100644 --- a/services/CollectionService/composer.lock +++ b/services/CollectionService/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "72756d6164e1895017dfad6f7dc6b745", - "content-hash": "073e008f0fc4878ea71877e80327b11c", + "hash": "867d904c5e16d9f6873d72cc65bec2bc", + "content-hash": "c3210ce7eb3a97dc912e46de5afe9202", "packages": [ { "name": "easyrdf/easyrdf", @@ -296,11 +296,11 @@ }, { "name": "islandora/resource-service", - "version": "dev-sprint-002-CollectionServ", + "version": "dev-CLAW-153", "dist": { "type": "path", - "url": "../ResourceServiceProvider/", - "reference": "e003f44811a41d385508795975428a03", + "url": "../ResourceService/", + "reference": "8a9d96c842c9148f4d2165ae06691d37b9389def", "shasum": null }, "require": { @@ -556,16 +556,16 @@ }, { "name": "ramsey/uuid", - "version": "3.1.0", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "3cc2dd253e296ce05f99635b2f633048adfbaa96" + "reference": "adee1ba4a6885ed800021a98dd69ae2394d695ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/3cc2dd253e296ce05f99635b2f633048adfbaa96", - "reference": "3cc2dd253e296ce05f99635b2f633048adfbaa96", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/adee1ba4a6885ed800021a98dd69ae2394d695ec", + "reference": "adee1ba4a6885ed800021a98dd69ae2394d695ec", "shasum": "" }, "require": { @@ -579,11 +579,12 @@ "ircmaxell/random-lib": "^1.1", "jakub-onderka/php-parallel-lint": "^0.9.0", "moontoast/math": "^1.1", - "phpunit/phpunit": "^4.7", + "phpunit/phpunit": "^4.7|^5.0", "satooshi/php-coveralls": "^0.6.1", "squizlabs/php_codesniffer": "^2.3" }, "suggest": { + "ext-libsodium": "Provides the PECL libsodium extension for use with the SodiumRandomGenerator", "ext-uuid": "Provides the PECL UUID extension for use with the PeclUuidTimeGenerator and PeclUuidRandomGenerator", "ircmaxell/random-lib": "Provides RandomLib for use with the RandomLibAdapter", "moontoast/math": "Provides support for converting UUID to 128-bit integer (in string form).", @@ -622,7 +623,7 @@ "identifier", "uuid" ], - "time": "2015-12-17 15:21:44" + "time": "2016-02-17 23:32:34" }, { "name": "silex/silex", diff --git a/services/CollectionService/config/settings.dev.yml b/services/CollectionService/config/settings.dev.yml index 129b9ad2d..541d32f08 100644 --- a/services/CollectionService/config/settings.dev.yml +++ b/services/CollectionService/config/settings.dev.yml @@ -3,9 +3,9 @@ islandora: apiVersion: 0.0.1 fedoraProtocol: http fedoraHost: "localhost:8080" - fedoraPath: /rest + fedoraPath: /fcrepo/rest tripleProtocol: http - tripleHost: "localhost:9999" + 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 diff --git a/services/CollectionService/src/Controller/CollectionController.php b/services/CollectionService/src/Controller/CollectionController.php new file mode 100644 index 000000000..8643313c6 --- /dev/null +++ b/services/CollectionService/src/Controller/CollectionController.php @@ -0,0 +1,225 @@ +uuidGenerator = $uuidGenerator; + } + + public function create(Application $app, Request $request, $id) { + $tx = $request->query->get('tx', ""); + //Check for format + $format = NULL; + try { + $format = \EasyRdf_Format::getFormat($contentType = $request->headers->get('Content-Type', 'text/turtle')); + } 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.2/'); + \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! + $fakeUuid = $this->uuidGenerator->generateV5("derp"); + $fakeIri = new \EasyRdf_ParsedUri('urn:uuid:' . $fakeUuid); + + $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, 'nfo:uuid')) { + $existingUuid = $graph->getLiteral($fakeIri, 'nfo:uuid'); + // Delete isl:hasURN to make it match the uuid + if (NULL != $graph->countValues($fakeIri, 'isl:hasURN')) { + $graph->delete($fakeIri, 'isl:hasURN'); + } + $graph->addResource($fakeIri, 'isl:hasURN', 'urn:uuid:'.$existingUuid); //Testing an Islandora Ontology! + } else { + //No UUID from the caller in RDF, lets put something there + // Need a random UUID because there wasn't one provided. + $newUuid = $this->uuidGenerator->generateV4(); + if (NULL != $graph->countValues($fakeIri, 'isl:hasURN')) { + $graph->delete($fakeIri, 'isl:hasURN'); + } + $graph->addLiteral($fakeIri,"nfo:uuid",$newUuid); //Keeps compat for now with other services + $graph->addResource($fakeIri,"isl:hasURN",'urn:uuid:'.$newUuid); //Testing an Islandora Ontology + } + //Restore LDP <> IRI on serialised graph + $pcmd_collection_rdf= str_replace($fakeIri, '', $graph->serialise('turtle')); + } + + $urlRoute = $request->getUriForPath('/islandora/resource/'); + + $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 + //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); + $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 + $responsePut = $app['islandora.resourcecontroller']->put($app, $subRequestPut, $responsePost->headers->get('location'), "members"); + if (201 == $responsePut->getStatusCode()) {// OK, indirect container created + //Include headers from the parent one, some of the last one. Basically rewrite everything + $putHeaders = $responsePut->getHeaders(); + //Guzzle psr7 response objects are inmutable. So we have to make this an array and add directly + $putHeaders['Link'] = array('<'.$responsePut->getBody().'>; rel="alternate"'); + $return_uuid = (isset($existingUuid) ? $existingUuid : $newUuid); + $putHeaders['Link'] = array('<'.$urlRoute.$return_uuid.'/members>; rel="hub"'); + $putHeaders['Location'] = array($urlRoute.$return_uuid); + //Should i care about the etag? + return new Response($putHeaders['Location'][0], 201, $putHeaders); + } + + return $responsePut; + } + //Abort if PCDM collection object could not be created + $app->abort($responsePost->getStatusCode(), 'Failed creating PCDM Collection'); + } + + /** + * Add a proxy object to the collection for the member object. + * + * @param Application $app + * The silex application. + * @param Request $request + * The Symfony request. + * @param string $id + * The UUID of the collection. + * @param string $member + * The UUID of the object to add to the collection. + */ + public function addMember(Application $app, Request $request, $id, $member) { + $tx = $request->query->get('tx', ""); + + $urlRoute = $request->getUriForPath('/islandora/resource/'); + + $members_uri = $app['islandora.idToUri']($member); + if (is_a($members_uri, 'Symfony\Component\HttpFoundation\Response')) { + return $members_uri; + } + + $members_proxy_rdf = $app['twig']->render('createOreProxy.ttl', array( + 'resource' => $members_uri, + )); + + $fullUri = $app['islandora.idToUri']($id); + if (is_a($fullUri, 'Symfony\Component\HttpFoundation\Response')) { + return $fullUri; + } + + $fullUri .= '/members'; + + $newRequest = Request::create($urlRoute . $id . '/members-add/' . $member , 'POST', array(), $request->cookies->all(), array(), $request->server->all(), $members_proxy_rdf); + $newRequest->headers->set('Content-type', 'text/turtle'); + $response = $app['islandora.resourcecontroller']->post($app, $newRequest, $fullUri); + if (201 == $response->getStatusCode()) { + return new Response($response->getBody(), 201, $response->getHeaders()); + } + //Abort if PCDM collection object could not be created + return $response; + //return new Response($response->getStatusCode(), 'Failed adding member to PCDM Collection'); + + } + + /** + * Remove the proxy object for the member from the collection. + * + * @param Application $app + * The silex application. + * @param Request $request + * The Symfony request. + * @param string $id + * The UUID of the collection. + * @param string $member + * The UUID of the object to remove from the collection. + */ + public function removeMember(Application $app, Request $request, $id, $member) { + $tx = $request->query->get('tx', ""); + $force = $request->query->get('force', 'FALSE'); + + $urlRoute = $request->getUriForPath('/islandora/resource/'); + + $collection_uri = $app['islandora.idToUri']($id); + if (is_object($collection_uri)) { + return $collection_uri; + } + + $member_uri = $app['islandora.idToUri']($member); + if (is_object($member_uri)) { + return $member_uri; + } + + $sparql_query = $app['twig']->render('findOreProxy.sparql', array( + 'collection_member' => $collection_uri . '/members', + 'resource' => $member_uri, + )); + try { + $sparql_result = $app['triplestore']->query($sparql_query); + } + catch (\Exception $e) { + $app->abort(503, 'Chullo says "Triple Store Not available"'); + } + if (count($sparql_result) > 0) { + $existing_transaction = (!empty($tx)); + $newRequest = Request::create($urlRoute . 'dummy/delete', 'POST', array(), $request->cookies->all(), array(), $request->server->all()); + if (!$existing_transaction) { + // If we don't have a transaction create one here + $response = $app['islandora.transactioncontroller']->create($app, $newRequest); + $tx = $app['islandora.transactioncontroller']->getId($response); + } + $newRequest = Request::create($urlRoute . 'dummy/delete?force=' . $force . '&tx=' . $tx, 'DELETE', array(), $request->cookies->all(), array(), $request->server->all()); + foreach ($sparql_result as $triple) { + $response = $app['islandora.resourcecontroller']->delete($app, $newRequest, $triple->obj->getUri(), ""); + if (204 != $response->getStatusCode()) { + $app->abort($response->getStatusCode(), 'Error deleting object'); + } + } + if (!$existing_transaction) { + // If this is not a passed in transaction, then we can commit it here. + $response = $app['islandora.transactioncontroller']->commit($app, $newRequest, $tx); + if (204 == $response->getStatusCode()) { + return $response; + } + else { + $app->abort($response->getStatusCode(), 'Failed removing member from PCDM Collection'); + } + } + } + // Not sure what to return if the transaction hasn't been committed yet. + return Response::create("", 204, array()); + } +} diff --git a/services/CollectionService/src/Provider/CollectionServiceProvider.php b/services/CollectionService/src/Provider/CollectionServiceProvider.php new file mode 100644 index 000000000..f89f66e6b --- /dev/null +++ b/services/CollectionService/src/Provider/CollectionServiceProvider.php @@ -0,0 +1,94 @@ +share($app->share(function() use ($app) { + return new UuidGenerator(); + })); + } + $app['islandora.collectioncontroller'] = $app->share(function() use ($app) { + return new \Islandora\CollectionService\Controller\CollectionController($app, $app['UuidGenerator']); + }); + 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 = $app['islandora.BasePath'].'/../config/settings.dev.yml'; + } + else { + $configFile = $app['islandora.BasePath'].'/../config/settings.yml'; + } + } + $settings = Yaml::parse(file_get_contents($configFile)); + return $settings; + }); + } + } + + function boot(Application $app) { + } + + /** + * Part of ControllerProviderInterface + */ + public function connect(Application $app) { + $CollectionControllers = $app['controllers_factory']; + // + // Define routing referring to controller services + // + + $CollectionControllers->post("/collection/{id}", "islandora.collectioncontroller:create") + ->value('id',"") + ->bind('islandora.collectionCreate'); + $CollectionControllers->post("/collection/{id}/member/{member}", "islandora.collectioncontroller:addMember") + ->bind('islandora.collectionAddMember'); + $CollectionControllers->delete("/collection/{id}/member/{member}", "islandora.collectioncontroller:removeMember") + ->bind('islandora.collectionRemoveMember'); + return $CollectionControllers; + } +} \ No newline at end of file diff --git a/services/CollectionService/src/index.php b/services/CollectionService/src/index.php index 6ea8515c3..9480fe70b 100644 --- a/services/CollectionService/src/index.php +++ b/services/CollectionService/src/index.php @@ -5,12 +5,15 @@ require_once __DIR__.'/../vendor/autoload.php'; use Silex\Application; -use Islandora\ResourceService\Provider\ResourceServiceProvider; +use Islandora\Chullo\Uuid\UuidGenerator; 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 Islandora\ResourceService\Provider\ResourceServiceProvider; +use Islandora\CollectionService\Provider\CollectionServiceProvider; +use Islandora\TransactionService\Provider\TransactionServiceProvider; date_default_timezone_set('UTC'); @@ -22,23 +25,24 @@ 'twig.path' => __DIR__.'/../templates', )); -$islandoraResourceServiceProvider = new \Islandora\ResourceService\Provider\ResourceServiceProvider; - +$islandoraResourceServiceProvider = new ResourceServiceProvider; //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'], -)); -//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']; +$islandoraTransactionService = new TransactionServiceProvider; + +$app->register($islandoraTransactionService); +$app->mount("/islandora", $islandoraTransactionService); + +$islandoraCollectionService = new CollectionServiceProvider; + +$app->register($islandoraCollectionService, array( + 'UuidGenerator' => new UuidGenerator(), +)); +$app->mount("/islandora", $islandoraCollectionService); /** * Convert returned Guzzle responses to Symfony responses. @@ -48,96 +52,6 @@ return new Response($psr7->getBody(), $psr7->getStatusCode(), $psr7->getHeaders()); }); -/** - * 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 { - $format = \EasyRdf_Format::getFormat($contentType = $request->headers->get('Content-Type', 'text/turtle')); - } 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($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 - $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= str_replace($fakeIri, '', $graph->serialise('turtle')); - } - - $urlRoute = $request->getUriForPath('/islandora/resource/'); - - $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 - //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); - $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 - $responsePut = $app['islandora.resourcecontroller']->put($app, $subRequestPut, $responsePost->headers->get('location'), "members"); - if (201 == $responsePut->getStatusCode()) {// OK, indirect container created - //Include headers from the parent one, some of the last one. Basically rewrite everything - $putHeaders = $responsePut->getHeaders(); - //Guzzle psr7 response objects are inmutable. So we have to make this an array and add directly - $putHeaders['Link'] = array('<'.$responsePut->getBody().'>; rel="alternate"'); - $putHeaders['Link'] = array('<'.$urlRoute.$tmpUuid.'/members>; rel="hub"'); - $putHeaders['Location'] = array($urlRoute.$tmpUuid); - //Should i care about the etag? - return new Response($putHeaders['Location'][0], 201, $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 diff --git a/services/CollectionService/templates/createOreProxy.ttl b/services/CollectionService/templates/createOreProxy.ttl new file mode 100644 index 000000000..a36577d81 --- /dev/null +++ b/services/CollectionService/templates/createOreProxy.ttl @@ -0,0 +1,5 @@ +@prefix pcdm: . +@prefix ore: . + +<> a pcdm:Object ; + ore:proxyFor <{{ resource }}> . \ No newline at end of file diff --git a/services/CollectionService/templates/findOreProxy.sparql b/services/CollectionService/templates/findOreProxy.sparql new file mode 100644 index 000000000..70cddabce --- /dev/null +++ b/services/CollectionService/templates/findOreProxy.sparql @@ -0,0 +1,6 @@ +PREFIX ore: +PREFIX ldp: +SELECT ?obj WHERE { + <{{ collection_member }}> ldp:contains ?obj . + ?obj ore:proxyFor <{{ resource }}> . +} diff --git a/services/ResourceService/composer.json b/services/ResourceService/composer.json index f68d44bff..c67f5693f 100644 --- a/services/ResourceService/composer.json +++ b/services/ResourceService/composer.json @@ -16,6 +16,10 @@ { "name": "Diego Pino Navarro", "email": "dpino@krayon.cl" + }, + { + "name": "Jared Whiklo", + "email": "jwhiklo@gmail.com" } ] } diff --git a/services/ResourceService/composer.lock b/services/ResourceService/composer.lock new file mode 100644 index 000000000..f78618fd5 --- /dev/null +++ b/services/ResourceService/composer.lock @@ -0,0 +1,1217 @@ +{ + "_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": "5ad34e59ae2a0d2abf07aa1e17549d75", + "content-hash": "e003f44811a41d385508795975428a03", + "packages": [ + { + "name": "easyrdf/easyrdf", + "version": "0.9.1", + "source": { + "type": "git", + "url": "https://github.com/njh/easyrdf.git", + "reference": "acd09dfe0555fbcfa254291e433c45fdd4652566" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/njh/easyrdf/zipball/acd09dfe0555fbcfa254291e433c45fdd4652566", + "reference": "acd09dfe0555fbcfa254291e433c45fdd4652566", + "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": "2015-02-27 09:45:49" + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.1.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "c6851d6e48f63b69357cbfa55bca116448140e0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/c6851d6e48f63b69357cbfa55bca116448140e0c", + "reference": "c6851d6e48f63b69357cbfa55bca116448140e0c", + "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-11-23 00:47:50" + }, + { + "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.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "f5d04bdd2881ac89abde1fb78cc234bce24327bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5d04bdd2881ac89abde1fb78cc234bce24327bb", + "reference": "f5d04bdd2881ac89abde1fb78cc234bce24327bb", + "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": "2016-01-23 01:23:02" + }, + { + "name": "islandora/chullo", + "version": "0.0.2", + "source": { + "type": "git", + "url": "https://github.com/Islandora-CLAW/chullo.git", + "reference": "e1e55a6fdb824a6955b0f72323f7070e3e528133" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Islandora-CLAW/chullo/zipball/e1e55a6fdb824a6955b0f72323f7070e3e528133", + "reference": "e1e55a6fdb824a6955b0f72323f7070e3e528133", + "shasum": "" + }, + "require": { + "easyrdf/easyrdf": "^0.9.1", + "guzzlehttp/guzzle": "^6.1.0", + "ml/json-ld": "^1.0.4", + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Islandora\\Chullo\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "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", + "time": "2016-02-10 21:37:57" + }, + { + "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.5", + "target-dir": "ML/JsonLD", + "source": { + "type": "git", + "url": "https://github.com/lanthaler/JsonLD.git", + "reference": "2f7f00a9daed844289135cc1cc99a75fc72a5438" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lanthaler/JsonLD/zipball/2f7f00a9daed844289135cc1cc99a75fc72a5438", + "reference": "2f7f00a9daed844289135cc1cc99a75fc72a5438", + "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": "2016-01-17 17:39:22" + }, + { + "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": "ramsey/uuid", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "adee1ba4a6885ed800021a98dd69ae2394d695ec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/adee1ba4a6885ed800021a98dd69ae2394d695ec", + "reference": "adee1ba4a6885ed800021a98dd69ae2394d695ec", + "shasum": "" + }, + "require": { + "php": ">=5.4" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "apigen/apigen": "^4.1", + "ircmaxell/random-lib": "^1.1", + "jakub-onderka/php-parallel-lint": "^0.9.0", + "moontoast/math": "^1.1", + "phpunit/phpunit": "^4.7|^5.0", + "satooshi/php-coveralls": "^0.6.1", + "squizlabs/php_codesniffer": "^2.3" + }, + "suggest": { + "ext-libsodium": "Provides the PECL libsodium extension for use with the SodiumRandomGenerator", + "ext-uuid": "Provides the PECL UUID extension for use with the PeclUuidTimeGenerator and PeclUuidRandomGenerator", + "ircmaxell/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "moontoast/math": "Provides support for converting UUID to 128-bit integer (in string form).", + "ramsey/uuid-console": "A console application for generating UUIDs with ramsey/uuid", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "type": "library", + "autoload": { + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marijn Huizendveld", + "email": "marijn.huizendveld@gmail.com" + }, + { + "name": "Thibaud Fabre", + "email": "thibaud@aztech.io" + }, + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "Formerly rhumsaa/uuid. A PHP 5.4+ library for generating RFC 4122 version 1, 3, 4, and 5 universally unique identifiers (UUID).", + "homepage": "https://github.com/ramsey/uuid", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "time": "2016-02-17 23:32:34" + }, + { + "name": "silex/silex", + "version": "v1.3.5", + "source": { + "type": "git", + "url": "https://github.com/silexphp/Silex.git", + "reference": "374c7e04040a6f781c90f7d746726a5daa78e783" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/silexphp/Silex/zipball/374c7e04040a6f781c90f7d746726a5daa78e783", + "reference": "374c7e04040a6f781c90f7d746726a5daa78e783", + "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": "2016-01-06 14:59:35" + }, + { + "name": "symfony/config", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "8c83ff9a2ffbed1e606bc816db11ddc2385a16ee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/8c83ff9a2ffbed1e606bc816db11ddc2385a16ee", + "reference": "8c83ff9a2ffbed1e606bc816db11ddc2385a16ee", + "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": "2016-01-21 09:38:31" + }, + { + "name": "symfony/debug", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "29606049ced1ec715475f88d1bbe587252a3476e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/29606049ced1ec715475f88d1bbe587252a3476e", + "reference": "29606049ced1ec715475f88d1bbe587252a3476e", + "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": "2016-01-27 05:14:46" + }, + { + "name": "symfony/event-dispatcher", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "4dd5df31a28c0f82b41cb1e1599b74b5dcdbdafa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/4dd5df31a28c0f82b41cb1e1599b74b5dcdbdafa", + "reference": "4dd5df31a28c0f82b41cb1e1599b74b5dcdbdafa", + "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": "2016-01-27 05:14:46" + }, + { + "name": "symfony/filesystem", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "064ac12afd2ceb8a2c1bfb7bed8e931c6dd1997f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/064ac12afd2ceb8a2c1bfb7bed8e931c6dd1997f", + "reference": "064ac12afd2ceb8a2c1bfb7bed8e931c6dd1997f", + "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": "2016-01-27 11:34:55" + }, + { + "name": "symfony/http-foundation", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "9344a87ceedfc50354a39653e54257ee9aa6a77d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/9344a87ceedfc50354a39653e54257ee9aa6a77d", + "reference": "9344a87ceedfc50354a39653e54257ee9aa6a77d", + "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": "2016-02-02 13:44:19" + }, + { + "name": "symfony/http-kernel", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "cec02604450481ac26710ca4249cc61b57b23942" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/cec02604450481ac26710ca4249cc61b57b23942", + "reference": "cec02604450481ac26710ca4249cc61b57b23942", + "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": "2016-02-03 12:38:44" + }, + { + "name": "symfony/routing", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "4686baa55a835e1c1ede9b86ba02415c8c8d6166" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/4686baa55a835e1c1ede9b86ba02415c8c8d6166", + "reference": "4686baa55a835e1c1ede9b86ba02415c8c8d6166", + "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": "2016-01-27 05:14:46" + }, + { + "name": "symfony/yaml", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "3cf0709d7fe936e97bee9e954382e449003f1d9a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/3cf0709d7fe936e97bee9e954382e449003f1d9a", + "reference": "3cf0709d7fe936e97bee9e954382e449003f1d9a", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "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 Yaml Component", + "homepage": "https://symfony.com", + "time": "2016-02-02 13:44:19" + }, + { + "name": "twig/twig", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8", + "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8", + "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.24-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": "2016-01-25 21:22:18" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/services/ResourceService/src/Provider/ResourceServiceProvider.php b/services/ResourceService/src/Provider/ResourceServiceProvider.php index 7746cfbb3..fa8a99a59 100644 --- a/services/ResourceService/src/Provider/ResourceServiceProvider.php +++ b/services/ResourceService/src/Provider/ResourceServiceProvider.php @@ -106,7 +106,8 @@ function register(Application $app) { 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)); + //$app->abort(404, sprintf('Failed getting resource Path for "%s" from triple store', $id)); + return Response::create(sprintf('Failed getting resource Path for "%s" from triple store', $id), 404); } else { // If $id is empty then assume we are dealing with fedora base rest endpoint diff --git a/services/TransactionService/.gitignore b/services/TransactionService/.gitignore index 9a3da4b81..576f653c9 100644 --- a/services/TransactionService/.gitignore +++ b/services/TransactionService/.gitignore @@ -1,3 +1,4 @@ composer.phar installer vendor +installer diff --git a/services/TransactionService/composer.json b/services/TransactionService/composer.json index 910d6ca34..0e41fce15 100644 --- a/services/TransactionService/composer.json +++ b/services/TransactionService/composer.json @@ -9,7 +9,7 @@ ], "require": { "islandora/chullo": "^0.0", - "islandora/resource-service": "dev-sprint-002", + "islandora/resource-service": "dev-sprint-002-working-vagrant", "silex/silex": "^1.3" }, "autoload": { diff --git a/services/TransactionService/composer.lock b/services/TransactionService/composer.lock new file mode 100644 index 000000000..4bbb739ef --- /dev/null +++ b/services/TransactionService/composer.lock @@ -0,0 +1,1250 @@ +{ + "_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": "938f9e89bb878a9379e291e95cb77256", + "content-hash": "6592a8879be3307f007a1547f49dc981", + "packages": [ + { + "name": "easyrdf/easyrdf", + "version": "0.9.1", + "source": { + "type": "git", + "url": "https://github.com/njh/easyrdf.git", + "reference": "acd09dfe0555fbcfa254291e433c45fdd4652566" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/njh/easyrdf/zipball/acd09dfe0555fbcfa254291e433c45fdd4652566", + "reference": "acd09dfe0555fbcfa254291e433c45fdd4652566", + "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": "2015-02-27 09:45:49" + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.1.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "c6851d6e48f63b69357cbfa55bca116448140e0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/c6851d6e48f63b69357cbfa55bca116448140e0c", + "reference": "c6851d6e48f63b69357cbfa55bca116448140e0c", + "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-11-23 00:47:50" + }, + { + "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.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "f5d04bdd2881ac89abde1fb78cc234bce24327bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5d04bdd2881ac89abde1fb78cc234bce24327bb", + "reference": "f5d04bdd2881ac89abde1fb78cc234bce24327bb", + "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": "2016-01-23 01:23:02" + }, + { + "name": "islandora/chullo", + "version": "0.0.2", + "source": { + "type": "git", + "url": "https://github.com/Islandora-CLAW/chullo.git", + "reference": "e1e55a6fdb824a6955b0f72323f7070e3e528133" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Islandora-CLAW/chullo/zipball/e1e55a6fdb824a6955b0f72323f7070e3e528133", + "reference": "e1e55a6fdb824a6955b0f72323f7070e3e528133", + "shasum": "" + }, + "require": { + "easyrdf/easyrdf": "^0.9.1", + "guzzlehttp/guzzle": "^6.1.0", + "ml/json-ld": "^1.0.4", + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Islandora\\Chullo\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "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", + "time": "2016-02-10 21:37:57" + }, + { + "name": "islandora/resource-service", + "version": "dev-CLAW-153", + "dist": { + "type": "path", + "url": "../ResourceService/", + "reference": "8a9d96c842c9148f4d2165ae06691d37b9389def", + "shasum": null + }, + "require": { + "islandora/chullo": "^0.0", + "ramsey/uuid": "^3.1", + "silex/silex": "^1.3", + "symfony/config": "^3.0", + "symfony/yaml": "^3.0", + "twig/twig": "^1.23" + }, + "type": "library", + "autoload": { + "psr-4": { + "Islandora\\ResourceService\\": "src/" + } + }, + "authors": [ + { + "name": "Diego Pino Navarro", + "email": "dpino@krayon.cl" + } + ], + "description": "RESTful service providing resources in Fedora 4" + }, + { + "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.5", + "target-dir": "ML/JsonLD", + "source": { + "type": "git", + "url": "https://github.com/lanthaler/JsonLD.git", + "reference": "2f7f00a9daed844289135cc1cc99a75fc72a5438" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lanthaler/JsonLD/zipball/2f7f00a9daed844289135cc1cc99a75fc72a5438", + "reference": "2f7f00a9daed844289135cc1cc99a75fc72a5438", + "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": "2016-01-17 17:39:22" + }, + { + "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": "ramsey/uuid", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "adee1ba4a6885ed800021a98dd69ae2394d695ec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/adee1ba4a6885ed800021a98dd69ae2394d695ec", + "reference": "adee1ba4a6885ed800021a98dd69ae2394d695ec", + "shasum": "" + }, + "require": { + "php": ">=5.4" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "apigen/apigen": "^4.1", + "ircmaxell/random-lib": "^1.1", + "jakub-onderka/php-parallel-lint": "^0.9.0", + "moontoast/math": "^1.1", + "phpunit/phpunit": "^4.7|^5.0", + "satooshi/php-coveralls": "^0.6.1", + "squizlabs/php_codesniffer": "^2.3" + }, + "suggest": { + "ext-libsodium": "Provides the PECL libsodium extension for use with the SodiumRandomGenerator", + "ext-uuid": "Provides the PECL UUID extension for use with the PeclUuidTimeGenerator and PeclUuidRandomGenerator", + "ircmaxell/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "moontoast/math": "Provides support for converting UUID to 128-bit integer (in string form).", + "ramsey/uuid-console": "A console application for generating UUIDs with ramsey/uuid", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "type": "library", + "autoload": { + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marijn Huizendveld", + "email": "marijn.huizendveld@gmail.com" + }, + { + "name": "Thibaud Fabre", + "email": "thibaud@aztech.io" + }, + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "Formerly rhumsaa/uuid. A PHP 5.4+ library for generating RFC 4122 version 1, 3, 4, and 5 universally unique identifiers (UUID).", + "homepage": "https://github.com/ramsey/uuid", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "time": "2016-02-17 23:32:34" + }, + { + "name": "silex/silex", + "version": "v1.3.5", + "source": { + "type": "git", + "url": "https://github.com/silexphp/Silex.git", + "reference": "374c7e04040a6f781c90f7d746726a5daa78e783" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/silexphp/Silex/zipball/374c7e04040a6f781c90f7d746726a5daa78e783", + "reference": "374c7e04040a6f781c90f7d746726a5daa78e783", + "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": "2016-01-06 14:59:35" + }, + { + "name": "symfony/config", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "8c83ff9a2ffbed1e606bc816db11ddc2385a16ee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/8c83ff9a2ffbed1e606bc816db11ddc2385a16ee", + "reference": "8c83ff9a2ffbed1e606bc816db11ddc2385a16ee", + "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": "2016-01-21 09:38:31" + }, + { + "name": "symfony/debug", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "29606049ced1ec715475f88d1bbe587252a3476e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/29606049ced1ec715475f88d1bbe587252a3476e", + "reference": "29606049ced1ec715475f88d1bbe587252a3476e", + "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": "2016-01-27 05:14:46" + }, + { + "name": "symfony/event-dispatcher", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "4dd5df31a28c0f82b41cb1e1599b74b5dcdbdafa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/4dd5df31a28c0f82b41cb1e1599b74b5dcdbdafa", + "reference": "4dd5df31a28c0f82b41cb1e1599b74b5dcdbdafa", + "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": "2016-01-27 05:14:46" + }, + { + "name": "symfony/filesystem", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "064ac12afd2ceb8a2c1bfb7bed8e931c6dd1997f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/064ac12afd2ceb8a2c1bfb7bed8e931c6dd1997f", + "reference": "064ac12afd2ceb8a2c1bfb7bed8e931c6dd1997f", + "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": "2016-01-27 11:34:55" + }, + { + "name": "symfony/http-foundation", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "9344a87ceedfc50354a39653e54257ee9aa6a77d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/9344a87ceedfc50354a39653e54257ee9aa6a77d", + "reference": "9344a87ceedfc50354a39653e54257ee9aa6a77d", + "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": "2016-02-02 13:44:19" + }, + { + "name": "symfony/http-kernel", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "cec02604450481ac26710ca4249cc61b57b23942" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/cec02604450481ac26710ca4249cc61b57b23942", + "reference": "cec02604450481ac26710ca4249cc61b57b23942", + "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": "2016-02-03 12:38:44" + }, + { + "name": "symfony/routing", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "4686baa55a835e1c1ede9b86ba02415c8c8d6166" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/4686baa55a835e1c1ede9b86ba02415c8c8d6166", + "reference": "4686baa55a835e1c1ede9b86ba02415c8c8d6166", + "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": "2016-01-27 05:14:46" + }, + { + "name": "symfony/yaml", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "3cf0709d7fe936e97bee9e954382e449003f1d9a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/3cf0709d7fe936e97bee9e954382e449003f1d9a", + "reference": "3cf0709d7fe936e97bee9e954382e449003f1d9a", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "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 Yaml Component", + "homepage": "https://symfony.com", + "time": "2016-02-02 13:44:19" + }, + { + "name": "twig/twig", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8", + "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8", + "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.24-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": "2016-01-25 21:22:18" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": { + "islandora/resource-service": 20 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/services/TransactionService/src/Controller/TransactionController.php b/services/TransactionService/src/Controller/TransactionController.php index f522cfca3..c5dd57e7f 100644 --- a/services/TransactionService/src/Controller/TransactionController.php +++ b/services/TransactionService/src/Controller/TransactionController.php @@ -44,4 +44,41 @@ public function rollback(Application $app, Request $request, $id) { return $response; } + /** + * Parse a response to get the transaction ID. + * + * @param $response + * Either a Symfony or Guzzle/Psr7 response. + * @return string + * The transaction ID. + */ + public function getId($response) { + if (get_class($response) == 'Symfony\Component\HttpFoundation\Response') { + if ($response->headers->has('location')) { + return $this->parseTransactionId($response->headers->get('location')); + } + } + if (get_class($response) == 'GuzzleHttp\Psr7\Response') { + if ($response->hasHeader('location')) { + return $this->parseTransactionId($response->getHeader('location')); + } + } + return NULL; + } + + /** + * Utility function to get the transaction ID from the Header. + * + * @param array|string $header + * array of headers or the single string. + * @return string + * the transaction ID. + */ + private function parseTransactionId($header) { + if (is_array($header)) { + $header = reset($header); + } + $ids = explode('tx:', $header); + return 'tx:' . $ids[1]; + } } diff --git a/services/composer.json b/services/composer.json new file mode 100644 index 000000000..d31f39675 --- /dev/null +++ b/services/composer.json @@ -0,0 +1,38 @@ +{ + "name": "islandora/services", + "description": "RESTful services container", + "repositories": [ + { + "type": "path", + "url": "ResourceService" + }, + { + "type": "path", + "url": "CollectionService" + }, + { + "type": "path", + "url": "TransactionService" + } + ], + "require": { + "islandora/chullo": "^0.0", + "islandora/resource-service": "dev-sprint-002-working-vagrant", + "islandora/collection-service": "dev-sprint-002-working-vagrant", + "silex/silex": "^1.3", + "symfony/config": "^3.0", + "twig/twig": "^1.23", + "symfony/yaml": "^3.0", + "ramsey/uuid": "^3.1" + }, + "autoload": { + "psr-4": {"Islandora\\Services\\": "src/"} + }, + "minimum-stability" : "dev", + "authors": [ + { + "name": "Jared Whiklo", + "email": "jwhiklo@gmail.com" + } + ] +} diff --git a/services/config/settings.dev.yml b/services/config/settings.dev.yml new file mode 100644 index 000000000..56525d86f --- /dev/null +++ b/services/config/settings.dev.yml @@ -0,0 +1,11 @@ +# Islandora Dev Settings to be used with $app['debug'] == TRUE +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})?" +# 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/src/index.php b/services/src/index.php new file mode 100644 index 000000000..0d1f5515b --- /dev/null +++ b/services/src/index.php @@ -0,0 +1,49 @@ +register(new \Silex\Provider\ServiceControllerServiceProvider()); +// TODO: Not register all template directories right now. +$app->register(new \Silex\Provider\TwigServiceProvider(), array( + 'twig.path' => array( + __DIR__ . '/../ResourceService/templates', + __DIR__ . '/../CollectionService/templates', + ), +)); + +$islandoraResourceServiceProvider = new ResourceServiceProvider; +$islandoraCollectionServiceProvider = new CollectionServiceProvider; +$islandoraTransactionServiceProvider = new TransactionServiceProvider; + +$app->register($islandoraResourceServiceProvider); +$app->register($islandoraCollectionServiceProvider); +$app->register($islandoraTransactionServiceProvider); +$app->mount("/islandora", $islandoraResourceServiceProvider); +$app->mount("/islandora", $islandoraCollectionServiceProvider); +$app->mount("/islandora", $islandoraTransactionServiceProvider); + +/** + * Convert returned Guzzle responses to Symfony responses, type hinted. + */ +$app->view(function (ResponseInterface $psr7) { + return new Response($psr7->getBody(), $psr7->getStatusCode(), $psr7->getHeaders()); +}); + +$app->run();