diff --git a/app/Http/Controllers/DoiController.php b/app/Http/Controllers/DoiController.php index 7f0dcdb..0fce0cd 100644 --- a/app/Http/Controllers/DoiController.php +++ b/app/Http/Controllers/DoiController.php @@ -78,7 +78,7 @@ class DoiController extends Controller $dataId = $request->input('publish_id'); // Setup stylesheet - $this->loadStyleSheet(public_path() .'\prefixes\doi_datacite.xslt'); + $this->loadStyleSheet(public_path() .'/prefixes/doi_datacite.xslt'); // set timestamp $date = new \DateTime(); @@ -114,14 +114,14 @@ class DoiController extends Controller $appUrl = config('app.url'); $landingPageUrl = $appUrl . "/dataset/" . $dataset->publish_id; $response = $this->doiClient->registerDoi($doiValue, $xmlMeta, $landingPageUrl); + // if operation successful if ($response->getStatusCode() == 201) { $doi = new DatasetIdentifier(); $doi['value'] = $doiValue; $doi['dataset_id'] = $dataset->id; $doi['type'] = "doi"; $doi['status'] = "registered"; - $doi['registration_ts'] = now(); - // $doi->save(); + $doi->save(); } } diff --git a/app/Models/DatasetIdentifier.php b/app/Models/DatasetIdentifier.php index 36f04a4..bde87bf 100644 --- a/app/Models/DatasetIdentifier.php +++ b/app/Models/DatasetIdentifier.php @@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model; class DatasetIdentifier extends Model { - protected $table = 'dataset_identifierss'; + protected $table = 'dataset_identifiers'; protected $guarded = array(); /** diff --git a/app/Tethys/Utils/DoiClient.php b/app/Tethys/Utils/DoiClient.php index ce300ea..45e12e2 100644 --- a/app/Tethys/Utils/DoiClient.php +++ b/app/Tethys/Utils/DoiClient.php @@ -33,7 +33,7 @@ class DoiClient implements DoiInterface } /** - * Creates a DOI or ARK with the given identifier + * Creates a DOI with the given identifier * * @param string $identifier The desired DOI identifier e.g. '10.5072/tethys.999', * @param $xmlMeta @@ -68,7 +68,6 @@ class DoiClient implements DoiInterface } // Response Codes // 201 Created: operation successful - // 400 Bad Request: invalid XML, wrong prefix // 401 Unauthorised: no login // 403 Forbidden: login problem, quota exceeded // 415 Wrong Content Type : Not including content type in the header. @@ -167,18 +166,74 @@ class DoiClient implements DoiInterface return ($statusCode == 200 && $landingPageURL == $body); } - public function getMetadataForDoi($identifier) + public function getMetadataForDoi($doiValue) { - // + $response = null; + $url = $this->serviceUrl . '/metadata/' . $doiValue; + try { + $client = new Client([ + 'auth' => [$this->username, $this->password], + 'base_uri' => $url, + 'verify' => false, + ]); + $response = $client->request('GET'); + } catch (\Exception $e) { + $message = 'request to ' . $url . ' failed with ' . $e->getMessage(); + throw new DoiClientException($message); + } + // Response Codes + // 200 OK: operation successful; + // 204 No Content: the DOI is known to DataCite Metadata Store (MDS), but no metadata have been registered; + // 401 Unauthorised: no login + // 403 Forbidden: permission problem or dataset belongs to another party; + // 404 Not Found: DOI does not exist in our database. + // 422 Unprocessable Entity Metadata failed validation against the DataCite Schema. + if ($response->getStatusCode() != 200) { + $message = 'unexpected DataCite MDS response code ' . $response->getStatusCode(); + // $this->log($message, 'err'); + throw new DoiClientException($message); + } + return $response; } - public function updateMetadataForDoi($identifier, $new_meta) + public function updateMetadataForDoi($doiValue, $newMeta) { - // + $response = null; + $url = $this->serviceUrl . '/metadata/' . $doiValue; + try { + $client = new Client([ + 'auth' => [$this->username, $this->password], + // 'base_uri' => $url, + 'verify' => false, + 'headers' => [ + 'Content-Type' => 'application/xml;charset=UTF-8', + ], + // 'body' => $xmlMeta, + ]); + // Provide the body as a string. + $response = $client->request('PUT', $url, [ + 'body' => $newMeta, + ]); + } catch (\Exception $e) { + $message = 'request to ' . $url . ' failed with ' . $e->getMessage(); + // $this->log($message, 'err'); + throw new DoiClientException($message); + } + // Response Codes + // 201 Created: operation successful + // 401 Unauthorised: no login + // 403 Forbidden: login problem, quota exceeded + // 415 Wrong Content Type : Not including content type in the header. + // 422 Unprocessable Entity : invalid XML + if ($response->getStatusCode() != 201) { + $message = 'unexpected DataCite MDS response code ' . $response->getStatusCode(); + // $this->log($message, 'err'); + throw new DoiClientException($message); + } } /** - * Markiert den Datensatz zur übergebenen DOI als inaktiv. + * Markiert den Datensatz zur übergebenen DOI als inaktiv - Status registered (not findable) * * @param $doiValue * diff --git a/database/migrations/2021_02_26_153027_create_dataset_identifiers_table.php b/database/migrations/2021_02_26_153027_create_dataset_identifiers_table.php index d7e2de4..e50c7c3 100644 --- a/database/migrations/2021_02_26_153027_create_dataset_identifiers_table.php +++ b/database/migrations/2021_02_26_153027_create_dataset_identifiers_table.php @@ -19,7 +19,7 @@ class CreateDatasetIdentifiersTable extends Migration // foreign key to: documents.id $table->integer('dataset_id')->unsigned(); - ; + $table->foreign('dataset_id')->references('id')->on('documents') ->onUpdate('cascade')->onDelete('cascade'); @@ -34,8 +34,6 @@ class CreateDatasetIdentifiersTable extends Migration 'status', ['draft', 'registered', 'findable'] )->nullable(); - // timestamp of DOI registration - $table->timestamp('registration_ts'); $table->timestamps(); }); } diff --git a/public/prefixes/doi_datacite.xslt b/public/prefixes/doi_datacite.xslt index 7b7c0e7..81797a4 100644 --- a/public/prefixes/doi_datacite.xslt +++ b/public/prefixes/doi_datacite.xslt @@ -227,11 +227,21 @@ - - - - - + + + + + + Title + + + + + + title + + + diff --git a/tests/Feature/DoiClientTest.php b/tests/Feature/DoiClientTest.php index 6d78beb..8152432 100644 --- a/tests/Feature/DoiClientTest.php +++ b/tests/Feature/DoiClientTest.php @@ -7,6 +7,7 @@ use Illuminate\Foundation\Testing\WithFaker; use Tests\TestCase; use App\Tethys\Utils\DoiClient; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Log; class DoiClientTest extends TestCase { @@ -21,48 +22,68 @@ class DoiClientTest extends TestCase // $response->assertStatus(200); // } - // public function testCheckDoi() - // { - // $client = new DoiClient(); - // // $this->setExpectedException('Opus\Doi\ClientException'); - // $result = $client->checkDoi( - // '10.5072/tethys-999', - // 'http://localhost/opus4/frontdoor/index/index/999' - // ); - // $this->assertTrue($result); - - // $result = $client->checkDoi( - // '10.5072/tethys-999', - // 'http://localhost/opus4/frontdoor/index/index/111' - // ); - // $this->assertFalse($result); - // } - - public function testRegisterDoiWithDataCiteTestAccount() + public function testCheckDoi() { - // $this->markTestSkipped( - // 'Test kann nur manuell gestartet werden (Zugangsdaten zum MDS-Testservice von DataCite erforderlich)' - // ); - - $myRequest = new Request(); - $myRequest->setMethod('POST'); - - $myRequest->request->add( - [ - 'publish_id' => 1, - 'path' => 'https://www.demo.laudatio-repository.org/foo' - ] + $client = new DoiClient(); + // $this->setExpectedException('Opus\Doi\ClientException'); + $publish_id = 1; + $prefix = config('tethys.datacite_prefix'); + $doiValue = $prefix . '/tethys.' . $publish_id; + $appUrl = config('app.url'); + $landingPageUrl = $appUrl . "/dataset/" . $publish_id; + $result = $client->checkDoi( + $doiValue, + $landingPageUrl ); + $this->assertTrue($result); - $doiController = new \App\Http\Controllers\DoiController(new DoiClient()); - $doiController->store($myRequest); + $result = $client->checkDoi( + '10.5072/tethys-999', + 'http://localhost/opus4/frontdoor/index/index/111' + ); + $this->assertFalse($result); + } + + // public function testRegisterDoiWithDataCiteTestAccount() + // { + // // $this->markTestSkipped( + // // 'Test kann nur manuell gestartet werden (Zugangsdaten zum MDS-Testservice von DataCite erforderlich)' + // // ); + + // $myRequest = new Request(); + // $myRequest->setMethod('POST'); + + // $myRequest->request->add( + // [ + // 'publish_id' => 1, + // // 'path' => 'https://www.demo.laudatio-repository.org/foo' + // ] + // ); + + // $doiController = new \App\Http\Controllers\DoiController(new DoiClient()); + // $doiController->store($myRequest); - // $client = new DoiClient(); - // $client->registerDoi( - // '10.5072/tethys-999', - // xmlMeta, - // 'http://localhost/opus4/frontdoor/index/index/999' - // ); + // // $client = new DoiClient(); + // // $client->registerDoi( + // // '10.5072/tethys-999', + // // xmlMeta, + // // 'http://localhost/opus4/frontdoor/index/index/999' + // // ); + // } + + public function testGetMetadataForDoi() + { + $client = new DoiClient(); + // $this->setExpectedException('Opus\Doi\ClientException'); + $publish_id = 1; + $prefix = config('tethys.datacite_prefix'); + $doiValue = $prefix . '/tethys.' . $publish_id; + $response = $client->getMetadataForDoi( + $doiValue + ); + $this->assertEquals(200, $response->getStatusCode()); + $testXml = new \SimpleXMLElement($response->getBody()->getContents()); + Log::alert($testXml->saveXML()); } }