# HG changeset patch # User ymh # Date 1449759953 -3600 # Node ID 037687868bc4ceffac153dea7a531baf85927049 # Parent a50cbd7d702f8bdd7b9510fb698bfbdc608dfc30 add viaf resolver service & api - add viaf api controller - add unit test - add viaf service provider diff -r a50cbd7d702f -r 037687868bc4 server/src/app/Facades/GuzzleFacade.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/app/Facades/GuzzleFacade.php Thu Dec 10 16:05:53 2015 +0100 @@ -0,0 +1,12 @@ +viafResolver = $viafResolver; + } + + /** + * Display the specified resource. + * + * @param int $id od comma separatedlist of ids + * @return \Illuminate\Http\Response + */ + public function show($id) + { + try { + return response()->json(['viafids' => $this->viafResolver->getNames(explode(",", $id))]); + } catch (ViafResolverException $e) { + abort($e->getCode(), $e->getMessage()); + } + } + +} diff -r a50cbd7d702f -r 037687868bc4 server/src/app/Http/routes.php --- a/server/src/app/Http/routes.php Tue Dec 01 16:49:37 2015 +0100 +++ b/server/src/app/Http/routes.php Thu Dec 10 16:05:53 2015 +0100 @@ -38,4 +38,6 @@ Route::group(['prefix' => 'api/v1'] , function() { Route::resource('documents', 'Api\DocumentController', ['only' => ['index', 'show']]); + Route::resource('viaf', 'Api\ViafController', + ['only' => ['show']]); }); diff -r a50cbd7d702f -r 037687868bc4 server/src/app/Libraries/Mappers/CocoonAbstractRdfMapper.php --- a/server/src/app/Libraries/Mappers/CocoonAbstractRdfMapper.php Tue Dec 01 16:49:37 2015 +0100 +++ b/server/src/app/Libraries/Mappers/CocoonAbstractRdfMapper.php Thu Dec 10 16:05:53 2015 +0100 @@ -133,7 +133,7 @@ foreach($collections as $coll) { if($coll instanceof Resource) { $collUri = $coll->getUri(); - if(strpos(strtolower($collUri), "collection", strlen(config('cocoon_doc_id_base_uri'))) !== FALSE) { + if(strpos(strtolower($collUri), "collection", strlen(config('corpusparole.cocoon_doc_id_base_uri'))) !== FALSE) { $collectionGraph = new Graph($collUri); $this->outputGraphes[$collUri] = $collectionGraph; $collectionGraph->resource($collUri, 'edm:Collection'); diff -r a50cbd7d702f -r 037687868bc4 server/src/app/Providers/GuzzleServiceProvider.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/app/Providers/GuzzleServiceProvider.php Thu Dec 10 16:05:53 2015 +0100 @@ -0,0 +1,25 @@ +app->bind('guzzle', function() { + $config = isset($this->app['config']['guzzle']) ? $this->app['config']['guzzle'] : []; + return new Client($config); + }); + } +} diff -r a50cbd7d702f -r 037687868bc4 server/src/app/Providers/ViafServiceProvider.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/app/Providers/ViafServiceProvider.php Thu Dec 10 16:05:53 2015 +0100 @@ -0,0 +1,24 @@ +app->bind('CorpusParole\Services\ViafResolverInterface', function($app) { + return new ViafResolver($app['guzzle']); + }); + } +} diff -r a50cbd7d702f -r 037687868bc4 server/src/app/Services/ViafResolver.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/app/Services/ViafResolver.php Thu Dec 10 16:05:53 2015 +0100 @@ -0,0 +1,114 @@ +client = $httpClient; + } + + /** + * make the viaf query. + */ + public function queryName($id) { + + $url = config('corpusparole.viaf_base_url').$id; + + try { + $response = $this->client->get($url."/", ['headers'=>['Accept' => 'application/rdf+xml'],]); + } + catch(ClientException $e) { + if($e->getResponse()->getStatusCode() === 404) { + return null; + } else { + throw new ViafResolverException( + $e->getMessage(), + $e->getResponse()->getStatusCode(), + $e + ); + } + } + catch(RequestException $e) { + throw new ViafResolverException( + $e->getMessage(), + $e->hasResponse()?$e->getResponse()->getStatusCode():500, + $e + ); + } + + $graph = new Graph($url, $response->getBody()); + $names = []; + foreach ($graph->allLiterals("<$url>", "schema:name") as $nameLit) { + $lang = $nameLit->getLang(); + if(!$lang && !isset($names[''])) { + $names[''] = $nameLit->getvalue(); + } + elseif (strpos($lang, 'fr') === 0 && !isset($names['fr'])) { + $names['fr'] = $nameLit->getvalue(); + } + elseif (strpos($lang, 'en') === 0 && !isset($names['en'])) { + $names['en'] = $nameLit->getvalue(); + } + } + + return (isset($names['fr'])) ? $names['fr'] : ((isset($names['en'])) ? $names['en'] : ((isset($names['']))? $names[''] : null)); + + } + + /** + * Check viaf id format + */ + private function checkViafIdFormat($viafid) { + return ctype_digit($viafid); + } + + /** + * Get name from Viaf id + * @param string $id The id to resolve. Can be an url starting with http://viaf.org/viaf/ + * @return a string with the name + */ + public function getName($id) { + $viafid = $id; + if(strpos($id, config('corpusparole.viaf_base_url')) === 0) { + $viafid = substr($id, strlen(config('corpusparole.viaf_base_url'))); + } + $viafid = rtrim($viafid, '/'); + + if(!$this->checkViafIdFormat($viafid)) { + throw new ViafResolverException("ViafId not in correct format", 400); + } + + $that = $this; + + return Cache::remember("viaf:$viafid", config('corpusparole.viaf_cache_expiration'), function() use ($that, $viafid) { + + return $that->queryName($viafid); + + }); + + } + + /** + * Get a list of names from an array of viaf ids. + * @param array $ids The array of ids to resolve. + * Each id can be an url starting with http://viaf.org/viaf/ + */ + public function getNames(array $ids) { + return array_combine($ids, array_map([$this,'getName'], $ids)); + } + + +} diff -r a50cbd7d702f -r 037687868bc4 server/src/app/Services/ViafResolverException.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/app/Services/ViafResolverException.php Thu Dec 10 16:05:53 2015 +0100 @@ -0,0 +1,6 @@ + 'Unintelligible Speech', ] ] + ], - ] + 'viaf_base_url' => 'http://viaf.org/viaf/', + 'viaf_cache_expiration' => 60*24*30 ]; diff -r a50cbd7d702f -r 037687868bc4 server/src/tests/Controllers/ViafControllerTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/tests/Controllers/ViafControllerTest.php Thu Dec 10 16:05:53 2015 +0100 @@ -0,0 +1,84 @@ +viafResolver = m::mock('CorpusParole\Services\ViafResolverInterface'); + $this->app->instance('CorpusParole\Services\ViafResolverInterface', $this->viafResolver); + } + + public function tearDown() { + m::close(); + parent::tearDown(); + } + + public function testShow() { + $this->viafResolver + ->shouldReceive('getNames') + ->with(['93752300', '56666014']) + ->once() + ->andReturn([ + '56666014' => 'Guylaine Brun-Trigaud', + '93752300' => 'Sonia Branca-Rosoff' + ]); + $response = $this->get('/api/v1/viaf/93752300,56666014')-> + seeJsonEquals(['viafids' => [ + '56666014' => 'Guylaine Brun-Trigaud', + '93752300' => 'Sonia Branca-Rosoff' + ]]); + } + + public function testShowOne() { + $this->viafResolver + ->shouldReceive('getNames') + ->with(['93752300']) + ->once() + ->andReturn([ + '93752300' => 'Sonia Branca-Rosoff' + ]); + $response = $this->get('/api/v1/viaf/93752300')-> + seeJsonEquals(['viafids' => [ + '93752300' => 'Sonia Branca-Rosoff' + ]]); + } + + public function testShowUnknown() { + $this->viafResolver + ->shouldReceive('getNames') + ->with(['12345']) + ->once() + ->andReturn([ + '12345' => null + ]); + $response = $this->get('/api/v1/viaf/12345')-> + seeJsonEquals(['viafids' => [ + '12345' => null + ]]); + } + + public function testShowMalformed() { + $this->viafResolver + ->shouldReceive('getNames') + ->with(['abcdef','ghij']) + ->once() + ->andThrow('CorpusParole\Services\ViafResolverException', "ViafId not in correct format", 400); + $response = $this->get('/api/v1/viaf/abcdef,ghij'); + + $this->assertResponseStatus(400); + } + +} diff -r a50cbd7d702f -r 037687868bc4 server/src/tests/Services/ViafResolverTest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/tests/Services/ViafResolverTest.php Thu Dec 10 16:05:53 2015 +0100 @@ -0,0 +1,179 @@ +566660141961-10-23Guylaine Brun-TrigaudWarning: skos:prefLabels are not ensured against change!Guylaine Brun-TrigaudGuylaine Brun-TrigaudWarning: skos:prefLabels are not ensured against change!Guylaine Brun-TrigaudGuylaine Brun-TrigaudWarning: skos:prefLabels are not ensured against change!Guylaine Brun-TrigaudGuylaine Brun-TrigaudGuylaine Brun-TrigaudGuylaine Brun- TrigaudGuylaine Brun-TrigaudTrigaudBrun-Trigaud, Guylaine, 1961-....Trigaud Guylaine Brun-Brun-Trigaud, Guylainehttp://opc4.kb.nl/PPN?PPN=072991968Brun-Trigaud, GuylaineTrigaud, Guylaine Brun-Brun-Trigaud, Guylaine, 1961-....Trigaud, Guylaine Brun-Brun-Trigaud, Guylaine, 1961-....Trigaud, Guylaine Brun- +EOT; + const VIAF_RDF_93752300 = <<93752300Sonia Branca-RosoffWarning: skos:prefLabels are not ensured against change!Sonia Branca-RosoffSonia Branca-RosoffWarning: skos:prefLabels are not ensured against change!Sonia Branca-RosoffSonia Branca-RosoffWarning: skos:prefLabels are not ensured against change!Sonia Branca-RosoffSonia Branca-RosoffWarning: skos:prefLabels are not ensured against change!Sonia Branca-RosoffSonia Branca-RosoffBCP47 tag for 'B2Q' is undetermined. Name is 'Sonia Branca-Rosoff'.Sonia Branca-RosoffSonia Branca-RosoffSonia Branca-RosoffSonia BrancaSoniaBrancaBrancaSonia CreusotSoniaCreusotSonia RosoffSoniaRosoffSonia Branca- RosoffSonia Branca-RosoffSonia Branca- RosoffSonia Branca-RosoffRosoffB2Q|0000099925Branca-Rosoff, Sonia.Branca SoniaRosoff SoniaBranca-Rosoff, Sonia.Branca, SoniaCreusot, SoniaRosoff, SoniaBranca-Rosoff, Sonia.Branca, SoniaRosoff, Sonia Branca-Branca-Rosoff, Sonia.http://opc4.kb.nl/PPN?PPN=146010671Branca-Rosoff, Sonia.Branca, SoniaCreusot, SoniaRosoff, SoniaRosoff, Sonia Branca-Branca-Rosoff, Sonia.Branca, SoniaRosoff, Sonia Branca-Branca-Rosoff, Sonia.Branca, SoniaRosoff, SoniaBranca-Rosoff, Sonia.Rosoff, Sonia Branca-. +EOT; + +//"container = []; + $history = Middleware::history($this->container); + $mock = new MockHandler([ + new Response(200, [], self::VIAF_RDF_56666014), + new Response(200, [], self::VIAF_RDF_93752300), + ]); + $handler = HandlerStack::create($mock); + $handler->push($history); + + $this->client = new Client(['handler' => $handler]); + + $mock404 = new MockHandler([ + new Response(404), + ]); + $this->client404 = new Client(['handler' => HandlerStack::create($mock404)]); + + $mock401 = new MockHandler([ + new Response(401, [], 'Unauthorized'), + new Response(500), + ]); + $this->client401 = new Client(['handler' => HandlerStack::create($mock401)]); + + $mock500 = new MockHandler([ + new Response(500, [], 'Internal Server Error'), + ]); + $this->client500 = new Client(['handler' => HandlerStack::create($mock500)]); + + } + + /** + * Jsut test the setup + * + * @return void + */ + public function testSetUp() { + $this->assertTrue(true); + } + + /** + * test getName + */ + public function testGetName() { + $resolver = $this->app->make('CorpusParole\Services\ViafResolver', [$this->client]); + $name = $resolver->getName('56666014'); + + $this->assertEquals('Guylaine Brun-Trigaud', $name, "Name must be Guylaine Brun-Trigaud"); + + $this->assertCount(1, $this->container); + + $this->assertEquals("http://viaf.org/viaf/56666014/", (string)$this->container[0]['request']->getUri()); + + } + + /** + * test getName + */ + public function testGetName93752300() { + $resolver = $this->app->make('CorpusParole\Services\ViafResolver', [$this->client]); + $name = $resolver->getName('56666014'); //first to consume responses + + $name = $resolver->getName('93752300'); + + $this->assertEquals('Sonia Branca-Rosoff', $name, "Name must be Sonia Branca-Rosoff"); + + $this->assertCount(2, $this->container); + + $this->assertEquals("http://viaf.org/viaf/93752300/", (string)$this->container[1]['request']->getUri()); + + } + + /** + * test unknown id + */ + public function testUnkownName404() { + $resolver = $this->app->make('CorpusParole\Services\ViafResolver', [$this->client404]); + + $name = $resolver->getName('12345'); + + $this->assertNull($name); + } + + /** + * test unknown id + */ + public function testUnkownName() { + $resolver = $this->app->make('CorpusParole\Services\ViafResolver', [$this->client]); + + $name = $resolver->getName('12345'); + + $this->assertNull($name); + } + + /** + * Test exception 401 + * @expectedException CorpusParole\Services\ViafResolverException + * @expectedExceptionMessage Client error: 401 + * @expectedExceptionCode 401 + */ + public function test401Error() { + $resolver = $this->app->make('CorpusParole\Services\ViafResolver', [$this->client401]); + + $name = $resolver->getName('12345'); + } + + + /** + * Test exception 500 + * @expectedException CorpusParole\Services\ViafResolverException + * @expectedExceptionMessage Server error: 500 + * @expectedExceptionCode 500 + */ + public function test500Error() { + $resolver = $this->app->make('CorpusParole\Services\ViafResolver', [$this->client500]); + + $name = $resolver->getName('12345'); + } + + /** + * Test exception malformed + * @expectedException CorpusParole\Services\ViafResolverException + * @expectedExceptionMessage ViafId not in correct format + * @expectedExceptionCode 400 + */ + public function testMalformedError() { + $resolver = $this->app->make('CorpusParole\Services\ViafResolver', [$this->client]); + + $name = $resolver->getName('abcd'); + } + + /** + * test getnames + */ + public function testGetNames() { + $resolver = $this->app->make('CorpusParole\Services\ViafResolver', [$this->client]); + $names = $resolver->getNames(['56666014', '93752300']); + + $this->assertCount(2, $names); + $this->assertArrayHasKey('56666014', $names); + $this->assertArrayHasKey('93752300', $names); + + $this->assertEquals('Sonia Branca-Rosoff', $names['93752300']); + $this->assertEquals('Guylaine Brun-Trigaud', $names['56666014']); + + } + +}