- added doi registration
Some checks failed
CI Pipeline / japa-tests (push) Failing after 57s

- npm updates for webpack-encore and postcss-loader
- DatasetExtension.ts: use relation contributors for PersonContributor
- added DoiClient.ts and DoiClientContract.ts
- rozes.ts: addes routes for creating and storing doi identifier
- addes xslt doi_datacite.xslt needed for registering DOI identifier
This commit is contained in:
Kaimbacher 2024-01-26 09:39:03 +01:00
parent ebc62d9117
commit c9ba7d6adc
22 changed files with 1836 additions and 677 deletions

View file

@ -2,6 +2,7 @@ import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
import { Client } from '@opensearch-project/opensearch';
import User from 'App/Models/User';
import Dataset from 'App/Models/Dataset';
import DatasetIdentifier from 'App/Models/DatasetIdentifier';
import XmlModel from 'App/Library/XmlModel';
import { XMLBuilder } from 'xmlbuilder2/lib/interfaces';
import { create } from 'xmlbuilder2';
@ -10,6 +11,12 @@ import { transform } from 'saxon-js';
import type { ModelQueryBuilderContract } from '@ioc:Adonis/Lucid/Orm';
import { schema, CustomMessages } from '@ioc:Adonis/Core/Validator';
import { DateTime } from 'luxon';
import Index from 'App/Library/Utils/Index';
import { getDomain } from 'App/Utils/utility-functions';
import { DoiClient } from 'App/Library/Doi/DoiClient';
import DoiClientException from 'App/Exceptions/DoiClientException';
import Logger from '@ioc:Adonis/Core/Logger';
import { HttpException } from 'node-exceptions';
// Create a new instance of the client
const client = new Client({ node: 'http://localhost:9200' }); // replace with your OpenSearch endpoint
@ -66,6 +73,7 @@ export default class DatasetsController {
.where('editor_id', user.id)
.doesntHave('identifier', 'and');
})
// .preload('identifier')
.preload('titles')
.preload('user', (query) => query.select('id', 'login'))
.preload('editor', (query) => query.select('id', 'login'))
@ -273,13 +281,79 @@ export default class DatasetsController {
dataset.publisher_name = publisherName;
if (await dataset.save()) {
const index_name = 'tethys-records';
await Index.indexDocument(dataset, index_name);
return response.toRoute('editor.dataset.list').flash('message', 'You have successfully published the dataset!');
}
}
public async create({}: HttpContextContract) {}
public async doiCreate({ request, inertia }: HttpContextContract) {
const id = request.param('id');
const dataset = await Dataset.query()
.where('id', id)
.preload('titles')
.preload('descriptions')
// .preload('identifier')
.preload('authors')
.firstOrFail();
return inertia.render('Editor/Dataset/Doi', {
dataset,
});
}
public async store({}: HttpContextContract) {}
public async doiStore({ request, response }: HttpContextContract) {
const dataId = request.param('publish_id');
const dataset = await Dataset.query()
// .preload('xmlCache')
.where('publish_id', dataId)
.firstOrFail();
const xmlMeta = (await Index.getDoiRegisterString(dataset)) as string;
let prefix = '';
let base_domain = '';
const datacite_environment = process.env.DATACITE_ENVIRONMENT || 'debug';
if (datacite_environment === 'debug') {
prefix = process.env.DATACITE_TEST_PREFIX || '';
base_domain = process.env.TEST_BASE_DOMAIN || '';
} else if (datacite_environment === 'production') {
prefix = process.env.DATACITE_PREFIX || '';
base_domain = process.env.BASE_DOMAIN || '';
}
// register DOI:
const doiValue = prefix + '/tethys.' + dataset.publish_id; //'10.21388/tethys.213'
const landingPageUrl = 'https://doi.' + getDomain(base_domain) + '/' + prefix + '/tethys.' + dataset.publish_id; //https://doi.dev.tethys.at/10.21388/tethys.213
const doiClient = new DoiClient();
const dataciteResponse = await doiClient.registerDoi(doiValue, xmlMeta, landingPageUrl);
if (dataciteResponse?.status === 201) {
// if response OK 201; save the Identifier value into db
const doiIdentifier = new DatasetIdentifier();
doiIdentifier.value = doiValue;
doiIdentifier.dataset_id = dataset.id;
doiIdentifier.type = 'doi';
doiIdentifier.status = 'findable';
// save modified date of datset for re-caching model in db an update the search index
dataset.server_date_modified = DateTime.now();
// save updated dataset to db an index to OpenSearch
try {
await dataset.related('identifier').save(doiIdentifier);
const index_name = 'tethys-records';
await Index.indexDocument(dataset, index_name);
} catch (error) {
Logger.error(`${__filename}: Indexing document ${dataset.id} failed: ${error.message}`);
// Log the error or handle it as needed
throw new HttpException(error.message);
}
return response.toRoute('editor.dataset.list').flash('message', 'You have successfully created a DOI for the dataset!');
} else {
const message = `Unexpected DataCite MDS response code ${dataciteResponse?.status}`;
// Log the error or handle it as needed
throw new DoiClientException(dataciteResponse?.status, message);
}
// return response.toRoute('editor.dataset.list').flash('message', xmlMeta);
}
public async show({}: HttpContextContract) {}
@ -404,8 +478,6 @@ export default class DatasetsController {
public async destroy({}: HttpContextContract) {}
public async syncOpensearch({}: HttpContextContract) {}
private async createXmlRecord(dataset: Dataset, datasetNode: XMLBuilder) {
const domNode = await this.getDatasetXmlDomNode(dataset);
if (domNode) {